create-byan-agent 1.1.2 → 1.2.0
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 +250 -177
- package/LICENSE +21 -21
- package/README.md +1245 -421
- package/bin/create-byan-agent-backup.js +220 -220
- package/bin/create-byan-agent-fixed.js +301 -301
- package/bin/create-byan-agent.js +322 -301
- package/lib/errors.js +61 -0
- package/lib/exit-codes.js +54 -0
- package/lib/platforms/claude-code.js +113 -0
- package/lib/platforms/codex.js +92 -0
- package/lib/platforms/copilot-cli.js +123 -0
- package/lib/platforms/index.js +14 -0
- package/lib/platforms/vscode.js +51 -0
- package/lib/utils/config-loader.js +79 -0
- package/lib/utils/file-utils.js +104 -0
- package/lib/utils/git-detector.js +35 -0
- package/lib/utils/logger.js +64 -0
- package/lib/utils/node-detector.js +58 -0
- package/lib/utils/os-detector.js +74 -0
- package/lib/utils/yaml-utils.js +87 -0
- package/lib/yanstaller/backuper.js +308 -0
- package/lib/yanstaller/detector.js +141 -0
- package/lib/yanstaller/index.js +93 -0
- package/lib/yanstaller/installer.js +225 -0
- package/lib/yanstaller/interviewer.js +250 -0
- package/lib/yanstaller/recommender.js +298 -0
- package/lib/yanstaller/troubleshooter.js +498 -0
- package/lib/yanstaller/validator.js +578 -0
- package/lib/yanstaller/wizard.js +211 -0
- package/package.json +61 -55
- package/templates/.github/agents/bmad-agent-bmad-master.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-agent-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-module-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-workflow-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-analyst.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-architect.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-dev.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-pm.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-quinn.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-sm.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-tech-writer.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-ux-designer.md +15 -15
- package/templates/.github/agents/bmad-agent-byan-test.md +32 -0
- package/templates/.github/agents/bmad-agent-byan.md +224 -224
- package/templates/.github/agents/bmad-agent-carmack.md +18 -0
- package/templates/.github/agents/bmad-agent-cis-brainstorming-coach.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-creative-problem-solver.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-design-thinking-coach.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-innovation-strategist.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-presentation-master.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-storyteller.md +15 -15
- package/templates/.github/agents/bmad-agent-marc.md +48 -48
- package/templates/.github/agents/bmad-agent-patnote.md +48 -0
- package/templates/.github/agents/bmad-agent-rachid.md +47 -47
- package/templates/.github/agents/bmad-agent-tea-tea.md +15 -15
- package/templates/.github/agents/bmad-agent-test-dynamic.md +21 -0
- package/templates/.github/agents/expert-merise-agile.md +1 -0
- package/templates/.github/agents/franck.md +379 -0
- package/templates/_bmad/bmb/agents/agent-builder.md +59 -59
- package/templates/_bmad/bmb/agents/byan-test.md +116 -116
- package/templates/_bmad/bmb/agents/byan.md +215 -215
- package/templates/_bmad/bmb/agents/marc.md +303 -303
- package/templates/_bmad/bmb/agents/module-builder.md +60 -60
- package/templates/_bmad/bmb/agents/patnote.md +495 -495
- package/templates/_bmad/bmb/agents/rachid.md +184 -184
- package/templates/_bmad/bmb/agents/workflow-builder.md +61 -61
- package/templates/_bmad/bmb/workflows/byan/data/mantras.yaml +272 -272
- package/templates/_bmad/bmb/workflows/byan/data/templates.yaml +59 -59
- package/templates/_bmad/bmb/workflows/byan/delete-agent-workflow.md +657 -657
- package/templates/_bmad/bmb/workflows/byan/edit-agent-workflow.md +688 -688
- package/templates/_bmad/bmb/workflows/byan/interview-workflow.md +753 -753
- package/templates/_bmad/bmb/workflows/byan/quick-create-workflow.md +450 -450
- package/templates/_bmad/bmb/workflows/byan/templates/base-agent-template.md +79 -79
- package/templates/_bmad/bmb/workflows/byan/validate-agent-workflow.md +676 -676
- package/templates/_bmad/core/agents/carmack.md +238 -238
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RECOMMENDER Module
|
|
3
|
+
*
|
|
4
|
+
* Analyzes project and recommends optimal BYAN configuration.
|
|
5
|
+
*
|
|
6
|
+
* Phase 2: 24h development
|
|
7
|
+
*
|
|
8
|
+
* @module yanstaller/recommender
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const fileUtils = require('../utils/file-utils');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {Object} Recommendation
|
|
16
|
+
* @property {string} mode - 'full' | 'minimal' | 'custom'
|
|
17
|
+
* @property {string[]} agents - Recommended agent names
|
|
18
|
+
* @property {string} reason - Why this recommendation
|
|
19
|
+
* @property {string} projectType - 'frontend' | 'backend' | 'fullstack' | 'library' | 'unknown'
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Analyze project and recommend configuration
|
|
24
|
+
*
|
|
25
|
+
* @param {import('./detector').DetectionResult} detection - Detection results
|
|
26
|
+
* @returns {Promise<Recommendation>}
|
|
27
|
+
*/
|
|
28
|
+
async function recommend(detection) {
|
|
29
|
+
const projectRoot = process.cwd();
|
|
30
|
+
|
|
31
|
+
// 1. Analyze project type
|
|
32
|
+
let projectType = 'unknown';
|
|
33
|
+
let framework = 'unknown';
|
|
34
|
+
|
|
35
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
36
|
+
if (await fileUtils.exists(packageJsonPath)) {
|
|
37
|
+
const analysis = await analyzePackageJson(packageJsonPath);
|
|
38
|
+
projectType = detectProjectType(analysis);
|
|
39
|
+
framework = analysis.framework;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Recommend agents based on type + platforms
|
|
43
|
+
const agents = getRecommendedAgents(projectType, detection.platforms);
|
|
44
|
+
|
|
45
|
+
// 3. Determine mode
|
|
46
|
+
const mode = agents.length > 10 ? 'full' : 'minimal';
|
|
47
|
+
|
|
48
|
+
// 4. Generate rationale
|
|
49
|
+
const reason = generateRationale(projectType, framework, agents, detection);
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
mode,
|
|
53
|
+
agents,
|
|
54
|
+
reason,
|
|
55
|
+
projectType
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Analyze package.json to detect stack
|
|
61
|
+
*
|
|
62
|
+
* @param {string} packageJsonPath - Path to package.json
|
|
63
|
+
* @returns {Promise<{isFrontend: boolean, isBackend: boolean, framework: string, deps: Object}>}
|
|
64
|
+
*/
|
|
65
|
+
async function analyzePackageJson(packageJsonPath) {
|
|
66
|
+
try {
|
|
67
|
+
const pkg = await fileUtils.readJSON(packageJsonPath);
|
|
68
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
69
|
+
|
|
70
|
+
const isFrontend = hasAny(deps, [
|
|
71
|
+
'react', 'react-dom',
|
|
72
|
+
'vue', '@vue/cli',
|
|
73
|
+
'angular', '@angular/core',
|
|
74
|
+
'svelte', '@sveltejs/kit',
|
|
75
|
+
'next', 'nuxt',
|
|
76
|
+
'gatsby', 'astro'
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
const isBackend = hasAny(deps, [
|
|
80
|
+
'express', 'fastify', 'koa', 'hapi',
|
|
81
|
+
'nestjs', '@nestjs/core',
|
|
82
|
+
'apollo-server', 'graphql',
|
|
83
|
+
'prisma', 'typeorm', 'sequelize',
|
|
84
|
+
'mongoose'
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
const framework = detectFramework(deps);
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
isFrontend,
|
|
91
|
+
isBackend,
|
|
92
|
+
framework,
|
|
93
|
+
deps
|
|
94
|
+
};
|
|
95
|
+
} catch (error) {
|
|
96
|
+
// File read error or invalid JSON
|
|
97
|
+
return {
|
|
98
|
+
isFrontend: false,
|
|
99
|
+
isBackend: false,
|
|
100
|
+
framework: 'unknown',
|
|
101
|
+
deps: {}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Detect project type from analysis
|
|
108
|
+
*
|
|
109
|
+
* @param {Object} analysis - Package.json analysis
|
|
110
|
+
* @returns {string} - 'frontend' | 'backend' | 'fullstack' | 'library' | 'unknown'
|
|
111
|
+
*/
|
|
112
|
+
function detectProjectType(analysis) {
|
|
113
|
+
if (analysis.isFrontend && analysis.isBackend) {
|
|
114
|
+
return 'fullstack';
|
|
115
|
+
}
|
|
116
|
+
if (analysis.isFrontend) {
|
|
117
|
+
return 'frontend';
|
|
118
|
+
}
|
|
119
|
+
if (analysis.isBackend) {
|
|
120
|
+
return 'backend';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check if it's a library (no UI dependencies, has build tools)
|
|
124
|
+
if (hasAny(analysis.deps, ['typescript', 'rollup', 'webpack', 'vite', 'tsup'])) {
|
|
125
|
+
return 'library';
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return 'unknown';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Detect framework from dependencies
|
|
133
|
+
*
|
|
134
|
+
* @param {Object} deps - Package dependencies
|
|
135
|
+
* @returns {string} - Framework name or 'unknown'
|
|
136
|
+
*/
|
|
137
|
+
function detectFramework(deps) {
|
|
138
|
+
const frameworks = {
|
|
139
|
+
'react': 'React',
|
|
140
|
+
'react-dom': 'React',
|
|
141
|
+
'next': 'Next.js',
|
|
142
|
+
'vue': 'Vue',
|
|
143
|
+
'@vue/cli': 'Vue',
|
|
144
|
+
'nuxt': 'Nuxt',
|
|
145
|
+
'angular': 'Angular',
|
|
146
|
+
'@angular/core': 'Angular',
|
|
147
|
+
'svelte': 'Svelte',
|
|
148
|
+
'@sveltejs/kit': 'SvelteKit',
|
|
149
|
+
'express': 'Express',
|
|
150
|
+
'fastify': 'Fastify',
|
|
151
|
+
'nestjs': 'NestJS',
|
|
152
|
+
'@nestjs/core': 'NestJS',
|
|
153
|
+
'gatsby': 'Gatsby',
|
|
154
|
+
'astro': 'Astro'
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
for (const [dep, framework] of Object.entries(frameworks)) {
|
|
158
|
+
if (deps[dep]) {
|
|
159
|
+
return framework;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return 'unknown';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get recommended agents based on project type
|
|
168
|
+
*
|
|
169
|
+
* @param {string} projectType - Project type
|
|
170
|
+
* @param {Array} platforms - Detected platforms
|
|
171
|
+
* @returns {string[]} - Agent names
|
|
172
|
+
*/
|
|
173
|
+
function getRecommendedAgents(projectType, platforms) {
|
|
174
|
+
const baseAgents = ['byan', 'rachid', 'patnote', 'carmack'];
|
|
175
|
+
|
|
176
|
+
// Add MARC if Copilot CLI detected
|
|
177
|
+
if (platforms.some(p => p.name === 'copilot-cli' && p.detected)) {
|
|
178
|
+
baseAgents.push('marc');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const recommendations = {
|
|
182
|
+
frontend: [...baseAgents, 'ux-designer', 'dev', 'quinn'],
|
|
183
|
+
backend: [...baseAgents, 'architect', 'dev', 'quinn'],
|
|
184
|
+
fullstack: [...baseAgents, 'architect', 'dev', 'ux-designer', 'quinn', 'pm'],
|
|
185
|
+
library: [...baseAgents, 'dev', 'tech-writer', 'quinn'],
|
|
186
|
+
unknown: baseAgents
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return recommendations[projectType] || baseAgents;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Generate rationale for recommendation
|
|
194
|
+
*
|
|
195
|
+
* @param {string} projectType - Project type
|
|
196
|
+
* @param {string} framework - Framework name
|
|
197
|
+
* @param {string[]} agents - Recommended agents
|
|
198
|
+
* @param {Object} detection - Detection results
|
|
199
|
+
* @returns {string} - Rationale text
|
|
200
|
+
*/
|
|
201
|
+
function generateRationale(projectType, framework, agents, detection) {
|
|
202
|
+
const reasons = [];
|
|
203
|
+
|
|
204
|
+
// Project type specific
|
|
205
|
+
switch (projectType) {
|
|
206
|
+
case 'frontend':
|
|
207
|
+
reasons.push(`Frontend project${framework !== 'unknown' ? ` (${framework})` : ''} benefits from UX design guidance`);
|
|
208
|
+
break;
|
|
209
|
+
case 'backend':
|
|
210
|
+
reasons.push(`Backend project${framework !== 'unknown' ? ` (${framework})` : ''} benefits from architecture patterns`);
|
|
211
|
+
break;
|
|
212
|
+
case 'fullstack':
|
|
213
|
+
reasons.push(`Fullstack project${framework !== 'unknown' ? ` (${framework})` : ''} needs both frontend and backend expertise`);
|
|
214
|
+
break;
|
|
215
|
+
case 'library':
|
|
216
|
+
reasons.push('Library project benefits from documentation and testing focus');
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
reasons.push('Default configuration for general projects');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Platform specific
|
|
223
|
+
const copilotDetected = detection.platforms.some(p => p.name === 'copilot-cli' && p.detected);
|
|
224
|
+
if (copilotDetected) {
|
|
225
|
+
reasons.push('MARC agent included for Copilot CLI integration');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Agent specific
|
|
229
|
+
if (agents.includes('dev')) {
|
|
230
|
+
reasons.push('DEV agent accelerates implementation with code generation');
|
|
231
|
+
}
|
|
232
|
+
if (agents.includes('quinn')) {
|
|
233
|
+
reasons.push('QUINN ensures test coverage and quality assurance');
|
|
234
|
+
}
|
|
235
|
+
if (agents.includes('architect')) {
|
|
236
|
+
reasons.push('ARCHITECT provides design patterns and system architecture');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return reasons.join('. ') + '.';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if any of the keys exist in object
|
|
244
|
+
*
|
|
245
|
+
* @param {Object} obj - Object to check
|
|
246
|
+
* @param {string[]} keys - Keys to look for
|
|
247
|
+
* @returns {boolean}
|
|
248
|
+
*/
|
|
249
|
+
function hasAny(obj, keys) {
|
|
250
|
+
return keys.some(key => obj[key]);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get agent list for installation mode
|
|
255
|
+
*
|
|
256
|
+
* @param {string} mode - 'full' | 'minimal' | 'custom'
|
|
257
|
+
* @param {string[]} [customAgents] - Custom agent selection
|
|
258
|
+
* @returns {string[]}
|
|
259
|
+
*/
|
|
260
|
+
function getAgentList(mode, customAgents = []) {
|
|
261
|
+
const MINIMAL_AGENTS = ['byan', 'rachid', 'marc', 'patnote', 'carmack'];
|
|
262
|
+
const FULL_AGENTS = [
|
|
263
|
+
// Core (5)
|
|
264
|
+
'byan', 'rachid', 'marc', 'patnote', 'carmack',
|
|
265
|
+
// BMM (9)
|
|
266
|
+
'analyst', 'pm', 'architect', 'dev', 'sm', 'quinn', 'ux-designer', 'tech-writer', 'quick-flow-solo-dev',
|
|
267
|
+
// BMB (3)
|
|
268
|
+
'agent-builder', 'module-builder', 'workflow-builder',
|
|
269
|
+
// TEA (1)
|
|
270
|
+
'tea',
|
|
271
|
+
// CIS (6)
|
|
272
|
+
'brainstorming-coach', 'creative-problem-solver', 'design-thinking-coach',
|
|
273
|
+
'innovation-strategist', 'presentation-master', 'storyteller',
|
|
274
|
+
// BYAN Test (1)
|
|
275
|
+
'byan-test'
|
|
276
|
+
];
|
|
277
|
+
|
|
278
|
+
switch (mode) {
|
|
279
|
+
case 'full':
|
|
280
|
+
return FULL_AGENTS;
|
|
281
|
+
case 'minimal':
|
|
282
|
+
return MINIMAL_AGENTS;
|
|
283
|
+
case 'custom':
|
|
284
|
+
return customAgents;
|
|
285
|
+
default:
|
|
286
|
+
return MINIMAL_AGENTS;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
module.exports = {
|
|
291
|
+
recommend,
|
|
292
|
+
analyzePackageJson,
|
|
293
|
+
getAgentList,
|
|
294
|
+
detectProjectType,
|
|
295
|
+
detectFramework,
|
|
296
|
+
getRecommendedAgents,
|
|
297
|
+
generateRationale
|
|
298
|
+
};
|