create-byan-agent 2.7.1 → 2.7.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.
@@ -0,0 +1,534 @@
1
+ /**
2
+ * Phase 2 Chat - Integrated conversation within the wizard
3
+ *
4
+ * Provides an in-wizard chat experience with the yanstaller-phase2 agent
5
+ * using copilot/codex CLI for AI responses.
6
+ */
7
+
8
+ const { spawnSync } = require('child_process');
9
+ const path = require('path');
10
+ const os = require('os');
11
+ const fs = require('fs-extra');
12
+ const inquirer = require('inquirer');
13
+ const chalk = require('chalk');
14
+ const ora = require('ora');
15
+
16
+ /**
17
+ * Cross-platform CLI command execution
18
+ * Uses spawnSync without shell on Unix (no character interpretation)
19
+ * Uses shell on Windows for .cmd file support
20
+ */
21
+ function runCliCommand(cmd, args, cwd, stdinInput) {
22
+ const isWindows = process.platform === 'win32';
23
+ const opts = {
24
+ encoding: 'utf8',
25
+ cwd: cwd,
26
+ timeout: 60000,
27
+ maxBuffer: 1024 * 1024,
28
+ stdio: ['pipe', 'pipe', 'pipe']
29
+ };
30
+
31
+ if (stdinInput) opts.input = stdinInput;
32
+ if (isWindows) opts.shell = true;
33
+
34
+ const res = spawnSync(cmd, args, opts);
35
+ if (res.error) throw res.error;
36
+
37
+ // Check for non-zero exit code with stderr
38
+ if (res.status !== 0 && res.stderr) {
39
+ const stderr = res.stderr.toString().trim();
40
+ if (stderr) throw new Error(stderr);
41
+ }
42
+
43
+ return (res.stdout || '').toString();
44
+ }
45
+
46
+ /**
47
+ * Build the initial context prompt from Phase 1 answers
48
+ */
49
+ function buildPhase1Context(interviewAnswers, detectedPlatforms, userName, language) {
50
+ const platformsDetected = [];
51
+ if (detectedPlatforms.copilot) platformsDetected.push('GitHub Copilot CLI');
52
+ if (detectedPlatforms.codex) platformsDetected.push('OpenAI Codex');
53
+ if (detectedPlatforms.claude) platformsDetected.push('Claude Code');
54
+ if (detectedPlatforms.vscode) platformsDetected.push('VSCode');
55
+
56
+ return {
57
+ user_name: userName || 'Developer',
58
+ communication_language: language || 'Francais',
59
+ project_type: interviewAnswers.projectType,
60
+ objectives: interviewAnswers.objectives,
61
+ team_size: interviewAnswers.teamSize,
62
+ experience: interviewAnswers.experience,
63
+ connectivity: interviewAnswers.connectivity,
64
+ gpu_available: interviewAnswers.gpu,
65
+ methodology: interviewAnswers.methodology,
66
+ domain: interviewAnswers.domain,
67
+ frequency: interviewAnswers.frequency,
68
+ quality_level: interviewAnswers.quality,
69
+ platforms_detected: platformsDetected,
70
+ platforms_string: platformsDetected.join(', ') || 'None'
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Generate the pre-prompt for Phase 2 agent
76
+ */
77
+ function generatePhase2Preprompt(context) {
78
+ return `
79
+ ## Profil Utilisateur Phase 1
80
+
81
+ - **Nom**: ${context.user_name}
82
+ - **Langue**: ${context.communication_language}
83
+ - **Type de projet**: ${context.project_type}
84
+ - **Domaine**: ${context.domain}
85
+ - **Objectifs**: ${Array.isArray(context.objectives) ? context.objectives.join(', ') : context.objectives}
86
+ - **Taille équipe**: ${context.team_size}
87
+ - **Expérience AI**: ${context.experience}
88
+ - **Connectivité**: ${context.connectivity}
89
+ - **GPU disponible**: ${context.gpu_available}
90
+ - **Méthodologie**: ${context.methodology}
91
+ - **Fréquence utilisation**: ${context.frequency}
92
+ - **Niveau qualité**: ${context.quality_level}
93
+ - **Plateformes détectées**: ${context.platforms_string}
94
+
95
+ ## Écosystème BYAN - Agents Disponibles
96
+
97
+ ### 🏛️ Hermes - Dispatcher Universel (NOUVEAU v2.3.2)
98
+ **Point d'entrée intelligent vers tout l'écosystème BYAN**
99
+ - **Rôle**: Router intelligent + Agent directory + Pipeline orchestrator
100
+ - **Invocation**: \`@hermes\`
101
+ - **Capabilities**:
102
+ - [LA] Liste 35+ agents par module (core, bmm, bmb, cis, tea)
103
+ - [REC] Smart routing: décris ta tâche → Hermes recommande les meilleurs agents
104
+ - [PIPE] Pipelines multi-agents (Feature Complete, Bug Fix, Idea→Code, etc.)
105
+ - [@agent] Invocation directe d'agents
106
+ - [?agent] Quick help sans charger l'agent
107
+ - **Quand recommander Hermes**: Toujours! C'est le meilleur point de départ pour découvrir et utiliser les agents BYAN.
108
+
109
+ ### 📦 Core Module (Foundation)
110
+ - **bmad-master**: Executor & Orchestrator (workflows, tasks)
111
+ - **yanstaller**: Smart installer (c'est moi!)
112
+ - **expert-merise-agile**: Conception Merise Agile + MCD/MCT
113
+
114
+ ### 🔨 BMB Module (Builders)
115
+ - **byan**: Agent creator via interview (12 questions, 64 mantras)
116
+ - **byan-v2**: Optimized BYAN v2
117
+ - **agent-builder**: Construction expert
118
+ - **marc**: GitHub Copilot integration specialist
119
+ - **rachid**: NPM/NPX deployment specialist
120
+ - **carmack**: Token optimizer
121
+ - **patnote**: Update manager
122
+
123
+ ### 💼 BMM Module (Management - SDLC)
124
+ - **analyst** (Mary): Business analysis, market research
125
+ - **architect** (Winston): System design, tech stack
126
+ - **dev** (Amelia): Implementation, coding
127
+ - **pm** (John): Product management, PRD
128
+ - **sm** (Bob): Scrum master, sprint planning
129
+ - **quinn**: QA engineer, tests
130
+ - **tech-writer** (Paige): Documentation
131
+ - **ux-designer** (Sally): UX/UI design
132
+ - **quick-flow-solo-dev** (Barry): Fast brownfield dev
133
+
134
+ ### 🎨 CIS Module (Creative & Innovation)
135
+ - **brainstorming-coach** (Carson): Ideation sessions
136
+ - **creative-problem-solver** (Dr. Quinn): Problem solving
137
+ - **design-thinking-coach** (Maya): Design thinking
138
+ - **innovation-strategist** (Victor): Innovation strategy
139
+ - **presentation-master** (Caravaggio): Presentations, slides
140
+ - **storyteller** (Sophia): Storytelling, narratives
141
+
142
+ ### 🧪 TEA Module (Testing)
143
+ - **tea** (Murat): Master test architect (ATDD, NFR, CI/CD)
144
+
145
+ ## Workflows Prédéfinis (via Hermes)
146
+
147
+ 1. **Feature Complete**: PM → Architect → UX → SM → Dev → Tea
148
+ 2. **Idea to Code**: PM → Architect → SM → Quick Flow
149
+ 3. **New Agent**: BYAN (handles entire flow)
150
+ 4. **Refactoring**: Architect → Dev → Tea
151
+ 5. **Bug Fix**: Dev → Quinn
152
+ 6. **Documentation**: Analyst → Tech Writer
153
+ 7. **Quality Complete**: Tea → Quinn → code-review
154
+
155
+ ## Instructions
156
+
157
+ Tu es YANSTALLER Phase 2. Commence par accueillir ${context.user_name} avec un résumé de son profil, puis engage une conversation pour configurer son écosystème d'agents BYAN.
158
+
159
+ **IMPORTANT**: Tu connais maintenant HERMES (v2.3.2) - le dispatcher universel. Recommande-le systématiquement comme point d'entrée pour découvrir et orchestrer les agents.
160
+
161
+ Adapte tes questions au domaine "${context.domain}" et au niveau d'expérience "${context.experience}".
162
+
163
+ Quand l'utilisateur dit "finaliser", "terminer" ou "c'est bon", génère la configuration JSON finale.
164
+ `.trim();
165
+ }
166
+
167
+ /**
168
+ * Send a message to the AI and get a response
169
+ *
170
+ * @param {string} message User message
171
+ * @param {string} systemContext System context/preprompt
172
+ * @param {string} conversationHistory Previous conversation
173
+ * @param {string} selectedPlatform Selected AI platform
174
+ * @param {string} projectRoot Project root directory
175
+ * @returns {Promise<string>} AI response
176
+ */
177
+ async function sendChatMessage(message, systemContext, conversationHistory, selectedPlatform, projectRoot) {
178
+ const fullPrompt = `${systemContext}
179
+
180
+ ## Historique de conversation:
181
+ ${conversationHistory}
182
+
183
+ ## Message utilisateur:
184
+ ${message}
185
+
186
+ ## Instructions:
187
+ Réponds de manière concise et naturelle. Si l'utilisateur dit "finaliser", génère le JSON de configuration.
188
+ Continue la conversation pour comprendre le projet et personnaliser les agents.`;
189
+
190
+ let result = '';
191
+
192
+ try {
193
+ if (selectedPlatform === 'copilot') {
194
+ result = runCliCommand('copilot', ['-p', fullPrompt, '-s'], projectRoot);
195
+ } else if (selectedPlatform === 'codex') {
196
+ // Codex takes prompt as argument to exec command
197
+ // --skip-git-repo-check needed when not in a trusted git repo
198
+ result = runCliCommand('codex', ['exec', '--skip-git-repo-check', fullPrompt], projectRoot);
199
+ } else if (selectedPlatform === 'claude') {
200
+ // Claude: separate system prompt from user query
201
+ // -p treats arg as user query; system context goes via --append-system-prompt-file
202
+ const claudeSystemCtx = `${systemContext}\n\n## Historique de conversation:\n${conversationHistory}\n\n## Instructions:\nRéponds de manière concise et naturelle. Si l'utilisateur dit "finaliser", génère le JSON de configuration.\nContinue la conversation pour comprendre le projet et personnaliser les agents.`;
203
+ const tmpFile = path.join(os.tmpdir(), `byan-claude-ctx-${Date.now()}.txt`);
204
+ fs.writeFileSync(tmpFile, claudeSystemCtx, 'utf8');
205
+ try {
206
+ result = runCliCommand('claude', [
207
+ '-p', message,
208
+ '--append-system-prompt-file', tmpFile
209
+ ], projectRoot);
210
+ } finally {
211
+ try { fs.unlinkSync(tmpFile); } catch(e) {}
212
+ }
213
+ } else {
214
+ throw new Error(`Platform not supported: ${selectedPlatform}`);
215
+ }
216
+ } catch (error) {
217
+ const errMsg = (error.message || '').toLowerCase();
218
+ console.error(chalk.red(`\n❌ Erreur ${selectedPlatform}: ${error.message}`));
219
+
220
+ // Platform-specific login guidance
221
+ if (selectedPlatform === 'claude' && (errMsg.includes('auth') || errMsg.includes('api') || errMsg.includes('key') || errMsg.includes('login') || errMsg.includes('401'))) {
222
+ console.log('');
223
+ console.log(chalk.yellow(' 💡 Pour se connecter à Claude Code:'));
224
+ console.log(chalk.cyan(' 1. claude login'));
225
+ console.log(chalk.gray(' 2. ou: export ANTHROPIC_API_KEY=sk-ant-...'));
226
+ console.log(chalk.gray(' 3. ou dans Claude Code: /login'));
227
+ } else if (selectedPlatform === 'copilot') {
228
+ console.log(chalk.gray(' → copilot auth'));
229
+ } else if (selectedPlatform === 'codex') {
230
+ console.log(chalk.gray(' → codex login'));
231
+ }
232
+
233
+ result = `Désolé, erreur de communication avec ${selectedPlatform}. Réessayez ou tapez "skip".`;
234
+ }
235
+
236
+ result = result.replace(/\x1b\[[0-9;]*m/g, '').trim();
237
+ return result;
238
+ }
239
+
240
+ /**
241
+ * Launch integrated chat within the wizard
242
+ *
243
+ * @param {Object} options Configuration options
244
+ * @param {Object} options.interviewAnswers Phase 1 answers
245
+ * @param {Object} options.detectedPlatforms Detected AI platforms
246
+ * @param {string} options.selectedPlatform Selected AI platform to use
247
+ * @param {string} options.projectRoot Project root directory
248
+ * @param {string} options.templateDir Templates directory
249
+ * @param {string} options.userName User name
250
+ * @param {string} options.language Communication language
251
+ * @returns {Promise<Object|null>} Phase 2 results or null if cancelled
252
+ */
253
+ async function launchPhase2Chat(options) {
254
+ const {
255
+ interviewAnswers,
256
+ detectedPlatforms,
257
+ selectedPlatform,
258
+ projectRoot,
259
+ templateDir,
260
+ userName,
261
+ language
262
+ } = options;
263
+
264
+ // Build context from Phase 1
265
+ const context = buildPhase1Context(interviewAnswers, detectedPlatforms, userName, language);
266
+ const systemContext = generatePhase2Preprompt(context);
267
+
268
+ // Pre-copy Phase 2 agent to project
269
+ const phase2AgentSource = path.join(templateDir, '.github', 'agents', 'bmad-agent-yanstaller-phase2.md');
270
+ const githubAgentsDir = path.join(projectRoot, '.github', 'agents');
271
+
272
+ if (await fs.pathExists(phase2AgentSource)) {
273
+ await fs.ensureDir(githubAgentsDir);
274
+ await fs.copy(phase2AgentSource, path.join(githubAgentsDir, 'bmad-agent-yanstaller-phase2.md'), { overwrite: true });
275
+ }
276
+
277
+ // Display Phase 2 header
278
+ console.log('');
279
+ console.log(chalk.magenta('╔════════════════════════════════════════════════════════════╗'));
280
+ console.log(chalk.magenta('║') + ' ' + chalk.magenta('║'));
281
+ console.log(chalk.magenta('║') + ` ${chalk.bold('💬 PHASE 2 - Conversation Yanstaller')} ` + chalk.magenta('║'));
282
+ console.log(chalk.magenta('║') + ` ${chalk.gray(`Mode interactif - Domaine: ${context.domain}`)} ` + chalk.magenta('║'));
283
+ console.log(chalk.magenta('║') + ' ' + chalk.magenta('║'));
284
+ console.log(chalk.magenta('╚════════════════════════════════════════════════════════════╝'));
285
+ console.log('');
286
+ console.log(chalk.gray(' Commandes: "finaliser" | "skip" | "aide"'));
287
+ console.log('');
288
+
289
+ // Check if any AI platform is available
290
+ if (!detectedPlatforms.copilot && !detectedPlatforms.codex && !detectedPlatforms.claude) {
291
+ console.log(chalk.yellow(' ⚠ Aucune plateforme AI détectée pour le chat.'));
292
+ return null;
293
+ }
294
+
295
+ // Get initial AI greeting
296
+ const spinner = ora('Yanstaller réfléchit...').start();
297
+ let conversationHistory = '';
298
+
299
+ const initialMessage = `Commence par accueillir l'utilisateur ${context.user_name} avec un résumé de son profil (domaine: ${context.domain}, objectifs: ${context.objectives ? context.objectives.join(', ') : 'non spécifiés'}) et pose ta première question pour personnaliser son installation BYAN.`;
300
+
301
+ const greeting = await sendChatMessage(initialMessage, systemContext, '', selectedPlatform, projectRoot);
302
+ spinner.stop();
303
+
304
+ console.log(chalk.cyan(' Yanstaller:'));
305
+ console.log(chalk.white(' ' + greeting.split('\n').join('\n ')));
306
+ console.log('');
307
+
308
+ conversationHistory += `Assistant: ${greeting}\n\n`;
309
+
310
+ // Chat loop using inquirer (avoids readline/inquirer conflict)
311
+ let phase2Config = null;
312
+ let continueChat = true;
313
+
314
+ while (continueChat) {
315
+ // Get user input using inquirer
316
+ const { userInput } = await inquirer.prompt([
317
+ {
318
+ type: 'input',
319
+ name: 'userInput',
320
+ message: '> Vous:',
321
+ prefix: ' '
322
+ }
323
+ ]);
324
+
325
+ const input = userInput.trim().toLowerCase();
326
+
327
+ // Handle special commands
328
+ if (input === 'skip' || input === 'passer') {
329
+ console.log(chalk.gray(' Phase 2 ignorée.'));
330
+ return null;
331
+ }
332
+
333
+ if (input === 'aide' || input === 'help') {
334
+ console.log('');
335
+ console.log(chalk.cyan(' Commandes disponibles:'));
336
+ console.log(chalk.gray(' finaliser - Générer la configuration et continuer'));
337
+ console.log(chalk.gray(' skip - Passer cette phase'));
338
+ console.log(chalk.gray(' aide - Afficher cette aide'));
339
+ console.log('');
340
+ continue;
341
+ }
342
+
343
+ // Add user message to history
344
+ conversationHistory += `Utilisateur: ${userInput}\n\n`;
345
+
346
+ // Check for finalization
347
+ const wantsFinal = input.includes('finaliser') ||
348
+ input.includes('terminer') ||
349
+ input.includes('c\'est bon') ||
350
+ input.includes('fini');
351
+
352
+ // Send to AI
353
+ const chatSpinner = ora('Yanstaller réfléchit...').start();
354
+
355
+ let aiPrompt = userInput;
356
+ if (wantsFinal) {
357
+ aiPrompt = `${userInput}
358
+
359
+ IMPORTANT: L'utilisateur veut finaliser. Génère maintenant la configuration JSON complète avec ce format exact:
360
+ \`\`\`json
361
+ {
362
+ "coreAgents": [...],
363
+ "optionalAgents": [...],
364
+ "agentRelationships": [...],
365
+ "projectStructure": {...},
366
+ "customAgentsToCreate": [...],
367
+ "recommendedModel": "string",
368
+ "rationale": "string"
369
+ }
370
+ \`\`\``;
371
+ }
372
+
373
+ const response = await sendChatMessage(aiPrompt, systemContext, conversationHistory, selectedPlatform, projectRoot);
374
+ chatSpinner.stop();
375
+
376
+ console.log('');
377
+ console.log(chalk.cyan(' Yanstaller:'));
378
+ console.log(chalk.white(' ' + response.split('\n').join('\n ')));
379
+ console.log('');
380
+
381
+ conversationHistory += `Assistant: ${response}\n\n`;
382
+
383
+ // Try to extract JSON config from response
384
+ const jsonMatch = response.match(/```json\s*([\s\S]*?)```/) ||
385
+ response.match(/\{[\s\S]*"coreAgents"[\s\S]*\}/);
386
+
387
+ if (jsonMatch) {
388
+ try {
389
+ const jsonStr = jsonMatch[1] || jsonMatch[0];
390
+ phase2Config = JSON.parse(jsonStr.trim());
391
+ console.log(chalk.green(' ✓ Configuration extraite!'));
392
+ console.log('');
393
+ continueChat = false;
394
+ } catch (e) {
395
+ // JSON parse failed, continue conversation
396
+ }
397
+ }
398
+
399
+ // If user wanted to finalize but we didn't get valid JSON
400
+ if (wantsFinal && !phase2Config) {
401
+ console.log(chalk.yellow(' ⚠ Configuration non générée. Réessayez "finaliser" ou "skip".'));
402
+ console.log('');
403
+ }
404
+ }
405
+
406
+ return phase2Config;
407
+ }
408
+
409
+ /**
410
+ * Fallback: Generate default config based on Phase 1 answers only
411
+ */
412
+ function generateDefaultConfig(interviewAnswers, detectedPlatforms, selectedPlatform) {
413
+ const domain = interviewAnswers.domain;
414
+ const quality = interviewAnswers.quality;
415
+
416
+ // Domain-based defaults
417
+ const domainConfigs = {
418
+ 'devops': {
419
+ coreAgents: [
420
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
421
+ { name: 'architect', role: 'Infrastructure design', expertise: ['cloud architecture', 'IaC'], complexity: 'complex' },
422
+ { name: 'devops', role: 'CI/CD pipeline management', expertise: ['automation', 'deployment'], complexity: 'complex' },
423
+ { name: 'security', role: 'Security scanning', expertise: ['container security', 'vulnerability analysis'], complexity: 'medium' }
424
+ ],
425
+ optionalAgents: [
426
+ { name: 'quinn', role: 'QA automation', expertise: ['testing'], when: 'Integration tests needed' }
427
+ ],
428
+ customAgentsToCreate: [
429
+ { name: 'pipeline-orchestrator', template: 'dev', focus: 'CI/CD optimization', mantras: ['IA-3 Automate Repeatable Work'] }
430
+ ],
431
+ projectStructure: { type: 'monorepo', folders: ['infra/', 'pipelines/', 'scripts/'], keyFiles: ['.github/workflows/', 'Dockerfile'] }
432
+ },
433
+ 'web': {
434
+ coreAgents: [
435
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
436
+ { name: 'ux-designer', role: 'User experience design', expertise: ['UI/UX', 'accessibility'], complexity: 'medium' },
437
+ { name: 'dev', role: 'Frontend development', expertise: ['React', 'CSS', 'TypeScript'], complexity: 'medium' },
438
+ { name: 'quinn', role: 'QA automation', expertise: ['E2E testing', 'visual regression'], complexity: 'medium' }
439
+ ],
440
+ optionalAgents: [
441
+ { name: 'tech-writer', role: 'Documentation', expertise: ['docs'], when: 'API documentation needed' }
442
+ ],
443
+ customAgentsToCreate: [
444
+ { name: 'component-architect', template: 'architect', focus: 'Component library design', mantras: ['IA-24 Clean Code'] }
445
+ ],
446
+ projectStructure: { type: 'monorepo', folders: ['src/', 'components/', 'tests/'], keyFiles: ['package.json', 'tsconfig.json'] }
447
+ },
448
+ 'backend/API': {
449
+ coreAgents: [
450
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
451
+ { name: 'architect', role: 'API design', expertise: ['REST', 'GraphQL', 'database'], complexity: 'complex' },
452
+ { name: 'dev', role: 'Backend development', expertise: ['Node.js', 'Python', 'Go'], complexity: 'medium' },
453
+ { name: 'data-analyst', role: 'Data modeling', expertise: ['Merise', 'SQL'], complexity: 'medium' }
454
+ ],
455
+ optionalAgents: [
456
+ { name: 'security', role: 'API security', expertise: ['OWASP'], when: 'Production deployment' }
457
+ ],
458
+ customAgentsToCreate: [
459
+ { name: 'api-designer', template: 'architect', focus: 'API contract design', mantras: ['IA-1 Trust But Verify'] }
460
+ ],
461
+ projectStructure: { type: 'microservices', folders: ['src/', 'api/', 'models/', 'tests/'], keyFiles: ['openapi.yaml', 'docker-compose.yml'] }
462
+ },
463
+ 'data/ML': {
464
+ coreAgents: [
465
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
466
+ { name: 'data-analyst', role: 'Data engineering', expertise: ['ETL', 'data modeling'], complexity: 'complex' },
467
+ { name: 'dev', role: 'ML development', expertise: ['Python', 'TensorFlow', 'PyTorch'], complexity: 'complex' },
468
+ { name: 'architect', role: 'Data architecture', expertise: ['data lakes', 'pipelines'], complexity: 'complex' }
469
+ ],
470
+ optionalAgents: [
471
+ { name: 'quinn', role: 'Model validation', expertise: ['testing'], when: 'Model accuracy validation needed' }
472
+ ],
473
+ customAgentsToCreate: [
474
+ { name: 'ml-ops', template: 'devops', focus: 'ML pipeline automation', mantras: ['IA-3 Automate Repeatable Work'] }
475
+ ],
476
+ projectStructure: { type: 'monorepo', folders: ['data/', 'models/', 'notebooks/', 'pipelines/'], keyFiles: ['requirements.txt', 'dvc.yaml'] }
477
+ },
478
+ 'mobile': {
479
+ coreAgents: [
480
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
481
+ { name: 'ux-designer', role: 'Mobile UX', expertise: ['iOS HIG', 'Material Design'], complexity: 'medium' },
482
+ { name: 'dev', role: 'Mobile development', expertise: ['React Native', 'Flutter', 'Swift'], complexity: 'medium' },
483
+ { name: 'quinn', role: 'Mobile testing', expertise: ['device testing', 'performance'], complexity: 'medium' }
484
+ ],
485
+ optionalAgents: [
486
+ { name: 'architect', role: 'App architecture', expertise: ['offline-first'], when: 'Offline support needed' }
487
+ ],
488
+ customAgentsToCreate: [
489
+ { name: 'platform-specialist', template: 'dev', focus: 'Platform-specific optimizations', mantras: ['IA-24 Clean Code'] }
490
+ ],
491
+ projectStructure: { type: 'monorepo', folders: ['src/', 'ios/', 'android/', 'shared/'], keyFiles: ['app.json', 'package.json'] }
492
+ },
493
+ 'multi-domain': {
494
+ coreAgents: [
495
+ { name: 'byan', role: 'Meta-agent creator', expertise: ['agent orchestration'], complexity: 'simple' },
496
+ { name: 'analyst', role: 'Requirements analysis', expertise: ['Merise', 'user stories'], complexity: 'medium' },
497
+ { name: 'architect', role: 'System design', expertise: ['full-stack architecture'], complexity: 'complex' },
498
+ { name: 'dev', role: 'Full-stack development', expertise: ['versatile'], complexity: 'medium' }
499
+ ],
500
+ optionalAgents: [
501
+ { name: 'pm', role: 'Project management', expertise: ['prioritization'], when: 'Multiple stakeholders' }
502
+ ],
503
+ customAgentsToCreate: [],
504
+ projectStructure: { type: 'monorepo', folders: ['frontend/', 'backend/', 'shared/', 'docs/'], keyFiles: ['package.json', 'docker-compose.yml'] }
505
+ }
506
+ };
507
+
508
+ const config = domainConfigs[domain] || domainConfigs['multi-domain'];
509
+
510
+ // Add common fields
511
+ config.agentRelationships = [
512
+ { from: 'analyst', to: 'architect', type: 'informs', description: 'Requirements inform architecture decisions' },
513
+ { from: 'architect', to: 'dev', type: 'triggers', description: 'Architecture triggers implementation' }
514
+ ];
515
+
516
+ // Set model based on quality and selected platform
517
+ if (selectedPlatform === 'claude') {
518
+ config.recommendedModel = quality === 'critical' ? 'claude-sonnet-4' : 'claude-haiku-4.5';
519
+ } else {
520
+ config.recommendedModel = quality === 'critical' ? 'claude-sonnet-4' :
521
+ quality === 'production' ? 'gpt-5.1-codex' : 'gpt-5-mini';
522
+ }
523
+
524
+ config.rationale = `Configuration par défaut pour projet ${domain}. Personnalisez via la conversation Phase 2 pour plus de précision.`;
525
+
526
+ return config;
527
+ }
528
+
529
+ module.exports = {
530
+ launchPhase2Chat,
531
+ generateDefaultConfig,
532
+ buildPhase1Context,
533
+ generatePhase2Preprompt
534
+ };