create-byan-agent 2.41.0 → 2.44.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/install/bin/byan-handoff.js +139 -0
  3. package/install/bin/byan-kanban.js +1 -1
  4. package/install/bin/create-byan-agent-v2.js +133 -112
  5. package/install/lib/byan-leantime-integration.js +2 -2
  6. package/install/lib/byan-web-integration.js +5 -5
  7. package/install/lib/claude-native-setup.js +11 -11
  8. package/install/lib/codex-native-setup.js +96 -4
  9. package/install/lib/exchange/agent-packager.js +1 -1
  10. package/install/lib/mcp-extensions/gdrive.js +5 -5
  11. package/install/lib/mcp-extensions/index.js +5 -5
  12. package/install/lib/phase2-chat.js +21 -21
  13. package/install/lib/platforms/claude-code.js +2 -2
  14. package/install/lib/project-agents-generator.js +4 -4
  15. package/install/lib/project-handoff.js +300 -0
  16. package/install/lib/rtk-integration.js +81 -14
  17. package/install/lib/staging-consent.js +1 -1
  18. package/install/lib/subagent-generator.js +2 -3
  19. package/install/lib/utils/logger.js +4 -4
  20. package/install/lib/utils/node-detector.js +1 -1
  21. package/install/lib/yanstaller/agent-launcher.js +1 -1
  22. package/install/lib/yanstaller/index.js +11 -116
  23. package/install/lib/yanstaller/platform-selector.js +11 -11
  24. package/install/src/byan-v2/dispatcher/task-router.js +1 -1
  25. package/install/src/index.js +1 -1
  26. package/install/src/webui/api.js +0 -13
  27. package/install/src/webui/chat/bridge.js +1 -1
  28. package/install/src/webui/chat/cli-detector.js +1 -1
  29. package/install/templates/.claude/CLAUDE.md +16 -0
  30. package/install/templates/.claude/rules/native-workflows.md +22 -14
  31. package/install/templates/.claude/settings.json +24 -24
  32. package/install/templates/.claude/skills/byan-byan/SKILL.md +14 -0
  33. package/install/templates/.claude/skills/byan-codex/SKILL.md +7 -0
  34. package/install/templates/.codex/skills/byan/SKILL.md +77 -0
  35. package/install/templates/_byan/COMPLETION-REPORT.md +0 -1
  36. package/install/templates/_byan/INDEX.md +6 -2
  37. package/install/templates/_byan/_config/workflow-manifest.csv +1 -1
  38. package/install/templates/_byan/core/activation/soul-activation.md +3 -3
  39. package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-lint-workflows.js +6 -3
  40. package/install/templates/_byan/mcp/byan-mcp-server/lib/native-tiers.js +35 -17
  41. package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-lint.js +38 -0
  42. package/install/templates/_byan/mcp/byan-mcp-server/skill-bundles-manifest.json +2 -2
  43. package/install/templates/_byan/worker/workers.md +1 -1
  44. package/install/templates/_byan/workflow/simple/byan/project-handoff-workflow.md +90 -0
  45. package/install/templates/dist/skill-bundles/byan-byan.zip +0 -0
  46. package/install/templates/dist/skill-bundles/byan-codex.zip +0 -0
  47. package/install/templates/docs/codex-auto-delegation.md +140 -0
  48. package/package.json +2 -1
  49. package/src/byan-v2/dispatcher/task-router.js +1 -1
  50. package/src/byan-v2/lib/layout-resolver.js +3 -6
  51. package/install/lib/yanstaller/installer.js +0 -138
  52. package/install/lib/yanstaller/interviewer.js +0 -88
  53. package/install/lib/yanstaller/recommender.js +0 -102
  54. package/install/lib/yanstaller/troubleshooter.js +0 -89
  55. package/install/lib/yanstaller/validator.js +0 -198
  56. package/install/lib/yanstaller/wizard.js +0 -109
  57. package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
  58. package/install/src/byan-v2/dispatcher/task-tool-interface.js +0 -123
  59. package/install/templates/_bmad/bmb/agents/agent-builder.md +0 -59
  60. package/install/templates/_bmad/bmb/agents/byan-test.md +0 -116
  61. package/install/templates/_bmad/bmb/agents/byan.md +0 -215
  62. package/install/templates/_bmad/bmb/agents/marc.md +0 -303
  63. package/install/templates/_bmad/bmb/agents/module-builder.md +0 -60
  64. package/install/templates/_bmad/bmb/agents/patnote.md +0 -495
  65. package/install/templates/_bmad/bmb/agents/rachid.md +0 -184
  66. package/install/templates/_bmad/bmb/agents/workflow-builder.md +0 -61
  67. package/install/templates/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -272
  68. package/install/templates/_bmad/bmb/workflows/byan/data/templates.yaml +0 -59
  69. package/install/templates/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -657
  70. package/install/templates/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -688
  71. package/install/templates/_bmad/bmb/workflows/byan/interview-workflow.md +0 -753
  72. package/install/templates/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -450
  73. package/install/templates/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -79
  74. package/install/templates/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -676
  75. package/install/templates/_bmad/core/agents/carmack.md +0 -238
  76. package/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
  77. package/src/byan-v2/dispatcher/task-tool-interface.js +0 -123
@@ -103,7 +103,7 @@ async function assertVersionFresh({ skip = false, timeoutMs = 5000 } = {}) {
103
103
  const banner = `
104
104
  ${chalk.blue('╔════════════════════════════════════════════════════════════╗')}
105
105
  ${chalk.blue('║')} ${chalk.blue('║')}
106
- ${chalk.blue('║')} ${chalk.bold('🏗️ BYAN INSTALLER v' + BYAN_VERSION)} ${chalk.blue('║')}
106
+ ${chalk.blue('║')} ${chalk.bold('BYAN INSTALLER v' + BYAN_VERSION)} ${chalk.blue('║')}
107
107
  ${chalk.blue('║')} ${chalk.gray('Builder of YAN - Agent Creator')} ${chalk.blue('║')}
108
108
  ${chalk.blue('║')} ${chalk.blue('║')}
109
109
  ${chalk.blue('║')} ${chalk.gray('Architecture: _byan/ + Model Selector')} ${chalk.blue('║')}
@@ -127,7 +127,7 @@ const getTemplateDir = () => {
127
127
  return devPath;
128
128
  }
129
129
 
130
- console.error(chalk.red('⚠️ WARNING: Template directory not found!'));
130
+ console.error(chalk.red('[WARN] WARNING: Template directory not found!'));
131
131
  console.error(chalk.red(` Searched: ${npmPackagePath}`));
132
132
  console.error(chalk.red(` Also searched: ${devPath}`));
133
133
  return null;
@@ -167,10 +167,10 @@ async function copyV2Runtime(templateDir, projectRoot, spinner) {
167
167
  if (await fs.pathExists(sourcePath)) {
168
168
  await fs.copy(sourcePath, destPath, { overwrite: false });
169
169
  spinner.text = `Installing ${file.desc}...`;
170
- console.log(chalk.green(` ${file.desc}: ${file.src} ${file.dest}`));
170
+ console.log(chalk.green(` [OK] ${file.desc}: ${file.src} -> ${file.dest}`));
171
171
  copiedCount++;
172
172
  } else {
173
- console.log(chalk.yellow(` Skipping ${file.desc} (not found in template)`));
173
+ console.log(chalk.yellow(` [WARN] Skipping ${file.desc} (not found in template)`));
174
174
  }
175
175
  }
176
176
 
@@ -292,7 +292,7 @@ async function mergePackageJson(templateDir, projectRoot, spinner) {
292
292
 
293
293
  await fs.writeJson(projectPkgPath, projectPkg, { spaces: 2 });
294
294
  spinner.text = 'Updated package.json with v2.0 dependencies';
295
- console.log(chalk.green(' package.json merged with v2.0 config'));
295
+ console.log(chalk.green(' [OK] package.json merged with v2.0 config'));
296
296
  return true;
297
297
  } else {
298
298
  // Create new package.json based on template
@@ -308,7 +308,7 @@ async function mergePackageJson(templateDir, projectRoot, spinner) {
308
308
 
309
309
  await fs.writeJson(projectPkgPath, newPkg, { spaces: 2 });
310
310
  spinner.text = 'Created package.json with v2.0 config';
311
- console.log(chalk.green(' package.json created'));
311
+ console.log(chalk.green(' [OK] package.json created'));
312
312
  return true;
313
313
  }
314
314
  }
@@ -364,7 +364,7 @@ async function install(options = {}) {
364
364
 
365
365
  if (v2Detection.isV2Available) {
366
366
  detectSpinner.succeed('BYAN v2.0 detected (Runtime + Platform)');
367
- console.log(chalk.cyan(' Architecture 4 Pilliers + v2.0 Core Components'));
367
+ console.log(chalk.cyan(' [INFO] Architecture 4 Pilliers + v2.0 Core Components'));
368
368
  } else {
369
369
  detectSpinner.succeed('BYAN v1.0 detected (Platform only)');
370
370
  }
@@ -375,17 +375,17 @@ async function install(options = {}) {
375
375
  const detectedPlatforms = await detectPlatforms();
376
376
  platformSpinner.succeed('Platform detection complete');
377
377
 
378
- console.log(chalk.cyan('\n📦 Installed Platforms:'));
379
- console.log(` OpenAI Codex: ${detectedPlatforms.codex ? chalk.green(' Detected') : chalk.gray(' Not found')}`);
380
- console.log(` Claude Code: ${detectedPlatforms.claude ? chalk.green(' Detected') : chalk.gray(' Not found')}`);
378
+ console.log(chalk.cyan('\nInstalled Platforms:'));
379
+ console.log(` OpenAI Codex: ${detectedPlatforms.codex ? chalk.green('[OK] Detected') : chalk.gray('[x] Not found')}`);
380
+ console.log(` Claude Code: ${detectedPlatforms.claude ? chalk.green('[OK] Detected') : chalk.gray('[x] Not found')}`);
381
381
  console.log('');
382
382
 
383
383
  // Calculate recommended model for installation
384
384
  const complexity = calculateInstallComplexity();
385
- console.log(chalk.cyan('🧠 Model Selector (Complexity Analysis):'));
385
+ console.log(chalk.cyan('Model Selector (Complexity Analysis):'));
386
386
  console.log(` Installation Score: ${chalk.yellow(complexity.score)} (simple task)`);
387
387
  console.log(` Recommended Model: ${chalk.green(complexity.recommended)}`);
388
- console.log(chalk.gray(' Optimized for cost efficiency during installation'));
388
+ console.log(chalk.gray(' -> Optimized for cost efficiency during installation'));
389
389
  console.log('');
390
390
 
391
391
  // Step 2.8: Installation mode selection
@@ -395,9 +395,9 @@ async function install(options = {}) {
395
395
  name: 'installMode',
396
396
  message: 'Choose installation mode:',
397
397
  choices: [
398
- { name: '🚀 AUTO - Quick install with smart defaults (Recommended)', value: 'auto' },
399
- { name: '🎯 CUSTOM - Guided interview with personalized recommendations', value: 'custom' },
400
- { name: '📋 MANUAL - Choose agents individually from the full catalog', value: 'manual' }
398
+ { name: 'AUTO - Quick install with smart defaults (Recommended)', value: 'auto' },
399
+ { name: 'CUSTOM - Guided interview with personalized recommendations', value: 'custom' },
400
+ { name: 'MANUAL - Choose agents individually from the full catalog', value: 'manual' }
401
401
  ],
402
402
  default: 'auto'
403
403
  }
@@ -414,7 +414,7 @@ async function install(options = {}) {
414
414
  console.log('');
415
415
  console.log(chalk.blue('╔════════════════════════════════════════════════════════════╗'));
416
416
  console.log(chalk.blue('║ ║'));
417
- console.log(chalk.blue('║ 📋 MANUAL MODE - Agent Catalog Selection ║'));
417
+ console.log(chalk.blue('║ MANUAL MODE - Agent Catalog Selection ║'));
418
418
  console.log(chalk.blue('║ Choose your agents from the full BYAN catalog ║'));
419
419
  console.log(chalk.blue('║ ║'));
420
420
  console.log(chalk.blue('╚════════════════════════════════════════════════════════════╝'));
@@ -422,12 +422,12 @@ async function install(options = {}) {
422
422
 
423
423
  // Step 1: Select target platform(s)
424
424
  const availableManualPlatforms = [];
425
- if (detectedPlatforms.codex) availableManualPlatforms.push({ name: '🔷 OpenAI Codex (skills: .codex/prompts/)', value: 'codex' });
426
- if (detectedPlatforms.claude) availableManualPlatforms.push({ name: '🧠 Claude Code (rules: .claude/)', value: 'claude' });
425
+ if (detectedPlatforms.codex) availableManualPlatforms.push({ name: 'OpenAI Codex (skills: .codex/prompts/)', value: 'codex' });
426
+ if (detectedPlatforms.claude) availableManualPlatforms.push({ name: 'Claude Code (rules: .claude/)', value: 'claude' });
427
427
 
428
428
  // Always allow manual selection even if not detected
429
- if (!detectedPlatforms.codex) availableManualPlatforms.push({ name: '🔷 OpenAI Codex (not detected)', value: 'codex' });
430
- if (!detectedPlatforms.claude) availableManualPlatforms.push({ name: '🧠 Claude Code (not detected)', value: 'claude' });
429
+ if (!detectedPlatforms.codex) availableManualPlatforms.push({ name: 'OpenAI Codex (not detected)', value: 'codex' });
430
+ if (!detectedPlatforms.claude) availableManualPlatforms.push({ name: 'Claude Code (not detected)', value: 'claude' });
431
431
 
432
432
  const { manualPlatforms } = await inquirer.prompt([{
433
433
  type: 'checkbox',
@@ -439,7 +439,7 @@ async function install(options = {}) {
439
439
 
440
440
  // Step 2: Show agent catalog grouped by category (module + role)
441
441
  console.log('');
442
- console.log(chalk.cyan('📦 Agent Catalog'));
442
+ console.log(chalk.cyan('Agent Catalog'));
443
443
  console.log(chalk.gray(' Hermes (dispatcher) is always installed - it routes tasks to the right agent.'));
444
444
  console.log(chalk.gray(' Agents are organized by role: Workflow, Context, and Worker.'));
445
445
  console.log('');
@@ -533,7 +533,7 @@ async function install(options = {}) {
533
533
  };
534
534
 
535
535
  console.log('');
536
- console.log(chalk.cyan('📋 Manual Selection Summary:'));
536
+ console.log(chalk.cyan('Manual Selection Summary:'));
537
537
  console.log(chalk.green(` Platforms: ${manualPlatforms.join(', ')}`));
538
538
  console.log(chalk.green(` Agents (${finalAgents.length}): ${finalAgents.join(', ')}`));
539
539
  console.log(chalk.gray(` Roles: dispatcher=hermes, workflow/context/worker agents selected`));
@@ -545,7 +545,7 @@ async function install(options = {}) {
545
545
  console.log('');
546
546
  console.log(chalk.blue('╔════════════════════════════════════════════════════════════╗'));
547
547
  console.log(chalk.blue('║ ║'));
548
- console.log(chalk.blue('║ 🎯 YANSTALLER - Intelligent Interview ║'));
548
+ console.log(chalk.blue('║ YANSTALLER - Intelligent Interview ║'));
549
549
  console.log(chalk.blue('║ Powered by bmad-agent-yanstaller ║'));
550
550
  console.log(chalk.blue('║ ║'));
551
551
  console.log(chalk.blue('╚════════════════════════════════════════════════════════════╝'));
@@ -710,7 +710,7 @@ async function install(options = {}) {
710
710
  interviewResults = JSON.parse(jsonStr);
711
711
 
712
712
  console.log('');
713
- console.log(chalk.cyan('📊 Yanstaller Recommendations:'));
713
+ console.log(chalk.cyan('Yanstaller Recommendations:'));
714
714
  if (interviewResults.platforms) {
715
715
  console.log(chalk.green(` Platforms: ${interviewResults.platforms.join(', ')}`));
716
716
  }
@@ -726,11 +726,11 @@ async function install(options = {}) {
726
726
  console.log(chalk.green(` Model: ${interviewResults.recommended_model || interviewComplexity}`));
727
727
  console.log(chalk.green(` Complexity: ${interviewResults.complexity_score || 'N/A'}`));
728
728
  } catch (parseErr) {
729
- console.log(chalk.yellow(' JSON parse error, using detection defaults'));
729
+ console.log(chalk.yellow(' [WARN] JSON parse error, using detection defaults'));
730
730
  interviewResults = null;
731
731
  }
732
732
  } else {
733
- console.log(chalk.yellow(' No JSON in agent response, using detection defaults'));
733
+ console.log(chalk.yellow(' [WARN] No JSON in agent response, using detection defaults'));
734
734
  interviewResults = null;
735
735
  }
736
736
  } catch (error) {
@@ -754,7 +754,7 @@ async function install(options = {}) {
754
754
  };
755
755
 
756
756
  console.log('');
757
- console.log(chalk.cyan('📊 Local Recommendations (from interview):'));
757
+ console.log(chalk.cyan('Local Recommendations (from interview):'));
758
758
  console.log(chalk.green(` Platforms: ${interviewResults.platforms.join(', ')}`));
759
759
  console.log(chalk.green(` Turbo Whisper: ${interviewResults.turboWhisper.mode}`));
760
760
  console.log(chalk.green(` Essential agents: ${interviewResults.agents.essential.join(', ')}`));
@@ -775,7 +775,7 @@ async function install(options = {}) {
775
775
  complexity_score: 15
776
776
  };
777
777
 
778
- console.log(chalk.yellow(' No AI platform detected, using defaults'));
778
+ console.log(chalk.yellow('[WARN] No AI platform detected, using defaults'));
779
779
  }
780
780
 
781
781
  // Cleanup temp prompt file
@@ -808,7 +808,7 @@ async function install(options = {}) {
808
808
 
809
809
  if (installMode === 'custom' && interviewResults) {
810
810
  // Use agent/interview recommendations
811
- console.log(chalk.blue('🎯 Recommandations personnalisées:'));
811
+ console.log(chalk.blue('Recommandations personnalisées:'));
812
812
  console.log('');
813
813
 
814
814
  // Platform recommendations (from agent JSON or detected platforms)
@@ -816,32 +816,32 @@ async function install(options = {}) {
816
816
  if (agentPlatforms.length > 0) {
817
817
  agentPlatforms.forEach(p => {
818
818
  recommendedPlatforms.push(p);
819
- console.log(chalk.green(` ${p} - Recommandé par yanstaller`));
819
+ console.log(chalk.green(` [OK] ${p} - Recommandé par yanstaller`));
820
820
  });
821
821
  } else {
822
- if (detectedPlatforms.codex) { recommendedPlatforms.push('codex'); console.log(chalk.green(' Codex - Détecté')); }
823
- if (detectedPlatforms.claude) { recommendedPlatforms.push('claude'); console.log(chalk.green(' Claude Code - Détecté')); }
822
+ if (detectedPlatforms.codex) { recommendedPlatforms.push('codex'); console.log(chalk.green(' [OK] Codex - Détecté')); }
823
+ if (detectedPlatforms.claude) { recommendedPlatforms.push('claude'); console.log(chalk.green(' [OK] Claude Code - Détecté')); }
824
824
  }
825
825
 
826
826
  // Turbo Whisper (from agent or interview data)
827
827
  if (interviewResults.turboWhisper) {
828
828
  recommendedTurboWhisper = interviewResults.turboWhisper.mode || 'skip';
829
829
  if (recommendedTurboWhisper !== 'skip') {
830
- console.log(chalk.cyan(` 🎤 Turbo Whisper (${recommendedTurboWhisper}) - ${interviewResults.turboWhisper.reason || 'Recommandé'}`));
830
+ console.log(chalk.cyan(` Turbo Whisper (${recommendedTurboWhisper}) - ${interviewResults.turboWhisper.reason || 'Recommandé'}`));
831
831
  }
832
832
  }
833
833
 
834
834
  // Agents recommendation
835
835
  if (interviewResults.agents) {
836
- console.log(chalk.cyan(` 📦 Agents essentiels: ${(interviewResults.agents.essential || []).join(', ')}`));
836
+ console.log(chalk.cyan(` Agents essentiels: ${(interviewResults.agents.essential || []).join(', ')}`));
837
837
  if (interviewResults.agents.optional && interviewResults.agents.optional.length > 0) {
838
- console.log(chalk.gray(` 📦 Agents optionnels: ${interviewResults.agents.optional.join(', ')}`));
838
+ console.log(chalk.gray(` Agents optionnels: ${interviewResults.agents.optional.join(', ')}`));
839
839
  }
840
840
  }
841
841
 
842
842
  // Model recommendation
843
843
  if (interviewResults.recommended_model) {
844
- console.log(chalk.cyan(` 🧠 Model recommandé: ${interviewResults.recommended_model} (score: ${interviewResults.complexity_score || 'N/A'})`));
844
+ console.log(chalk.cyan(` Model recommandé: ${interviewResults.recommended_model} (score: ${interviewResults.complexity_score || 'N/A'})`));
845
845
  }
846
846
 
847
847
  console.log('');
@@ -850,8 +850,8 @@ async function install(options = {}) {
850
850
  let selectedPlatform = null;
851
851
  const availablePlatforms = [];
852
852
 
853
- if (detectedPlatforms.codex) availablePlatforms.push({ name: '🔷 OpenAI Codex', value: 'codex' });
854
- if (detectedPlatforms.claude) availablePlatforms.push({ name: '🧠 Claude Code (Anthropic)', value: 'claude' });
853
+ if (detectedPlatforms.codex) availablePlatforms.push({ name: 'OpenAI Codex', value: 'codex' });
854
+ if (detectedPlatforms.claude) availablePlatforms.push({ name: 'Claude Code (Anthropic)', value: 'claude' });
855
855
 
856
856
  if (availablePlatforms.length > 1) {
857
857
  const { platform } = await inquirer.prompt([{
@@ -864,9 +864,9 @@ async function install(options = {}) {
864
864
  selectedPlatform = platform;
865
865
  } else if (availablePlatforms.length === 1) {
866
866
  selectedPlatform = availablePlatforms[0].value;
867
- console.log(chalk.cyan(`🤖 Plateforme détectée: ${availablePlatforms[0].name}`));
867
+ console.log(chalk.cyan(`Plateforme détectée: ${availablePlatforms[0].name}`));
868
868
  } else {
869
- console.log(chalk.red(' Aucune plateforme IA détectée. Installation en mode AUTO.'));
869
+ console.log(chalk.red('[ERROR] Aucune plateforme IA détectée. Installation en mode AUTO.'));
870
870
  installMode = 'auto';
871
871
  }
872
872
 
@@ -875,14 +875,14 @@ async function install(options = {}) {
875
875
  const oldModel = interviewResults.recommended_model || '';
876
876
  if (oldModel.includes('gpt')) {
877
877
  interviewResults.recommended_model = 'claude-haiku-4.5';
878
- console.log(chalk.cyan(` 🧠 Model adapté: claude-haiku-4.5 (plateforme: Claude)`));
878
+ console.log(chalk.cyan(` Model adapté: claude-haiku-4.5 (plateforme: Claude)`));
879
879
  }
880
880
  }
881
881
 
882
882
  // Verify authentication for selected platform
883
883
  if (selectedPlatform && installMode === 'custom') {
884
884
  console.log('');
885
- console.log(chalk.gray('🔐 Vérification de l\'authentification...'));
885
+ console.log(chalk.gray('Vérification de l\'authentification...'));
886
886
 
887
887
  let isAuthenticated = false;
888
888
 
@@ -921,11 +921,11 @@ async function install(options = {}) {
921
921
  }
922
922
 
923
923
  isAuthenticated = true;
924
- console.log(chalk.green(`✓ ${selectedPlatform} authentifié et disponible`));
924
+ console.log(chalk.green(`[OK] ${selectedPlatform} authentifié et disponible`));
925
925
 
926
926
  } catch (error) {
927
927
  console.log('');
928
- console.log(chalk.yellow(`⚠️ ${selectedPlatform} n'est pas authentifié ou non disponible`));
928
+ console.log(chalk.yellow(`[WARN] ${selectedPlatform} n'est pas authentifié ou non disponible`));
929
929
  console.log(chalk.gray(` Erreur: ${(error.message || '').substring(0, 120)}`));
930
930
  console.log('');
931
931
  console.log(chalk.bold(' Pour vous connecter:'));
@@ -948,14 +948,14 @@ async function install(options = {}) {
948
948
  name: 'authAction',
949
949
  message: 'Que souhaitez-vous faire?',
950
950
  choices: [
951
- { name: '🔄 Réessayer (après connexion dans un autre terminal)', value: 'retry' },
952
- { name: 'Continuer en mode AUTO (sans conversation IA)', value: 'auto' },
953
- { name: ' Annuler l\'installation', value: 'cancel' }
951
+ { name: 'Réessayer (après connexion dans un autre terminal)', value: 'retry' },
952
+ { name: 'Continuer en mode AUTO (sans conversation IA)', value: 'auto' },
953
+ { name: '[ERROR] Annuler l\'installation', value: 'cancel' }
954
954
  ]
955
955
  }]);
956
956
 
957
957
  if (authAction === 'retry') {
958
- console.log(chalk.gray('\n🔐 Nouvelle vérification...'));
958
+ console.log(chalk.gray('\nNouvelle vérification...'));
959
959
  continue;
960
960
  } else if (authAction === 'auto') {
961
961
  installMode = 'auto';
@@ -978,9 +978,9 @@ async function install(options = {}) {
978
978
  name: 'enterPhase2',
979
979
  message: 'Phase 2 - Configuration avancée?',
980
980
  choices: [
981
- { name: '💬 Chat - Conversation personnalisée avec Yanstaller', value: 'chat' },
982
- { name: 'Auto - Configuration par défaut (rapide)', value: 'auto' },
983
- { name: '⏭️ Skip - Passer Phase 2', value: 'skip' }
981
+ { name: 'Chat - Conversation personnalisée avec Yanstaller', value: 'chat' },
982
+ { name: 'Auto - Configuration par défaut (rapide)', value: 'auto' },
983
+ { name: 'Skip - Passer Phase 2', value: 'skip' }
984
984
  ],
985
985
  default: 'chat'
986
986
  }]);
@@ -1023,7 +1023,7 @@ async function install(options = {}) {
1023
1023
  // Display Phase 2 results if available
1024
1024
  if (phase2Results) {
1025
1025
  console.log('');
1026
- console.log(chalk.cyan('📋 Configuration Agents:'));
1026
+ console.log(chalk.cyan('Configuration Agents:'));
1027
1027
  if (phase2Results.coreAgents) {
1028
1028
  console.log(chalk.green(` Core: ${phase2Results.coreAgents.map(a => a.name).join(', ')}`));
1029
1029
  }
@@ -1039,7 +1039,7 @@ async function install(options = {}) {
1039
1039
  try {
1040
1040
  const outputDir = path.join(projectRoot, '_byan-output');
1041
1041
  const docPath = await generateProjectAgentsDoc(phase2Results, interviewAnswers, {}, outputDir);
1042
- console.log(chalk.green(` Généré: ${path.relative(projectRoot, docPath)}`));
1042
+ console.log(chalk.green(` [OK] Généré: ${path.relative(projectRoot, docPath)}`));
1043
1043
  console.log('');
1044
1044
  } catch (error) {
1045
1045
  // Silent fail - document generation is optional
@@ -1056,12 +1056,12 @@ async function install(options = {}) {
1056
1056
  // In MANUAL mode, use the first selected platform as primary
1057
1057
  // (all selected platforms will be used for stub generation)
1058
1058
  platform = manualSelection.platforms.length === 1 ? manualSelection.platforms[0] : 'all';
1059
- console.log(chalk.cyan(`📦 Platform(s): ${manualSelection.platforms.join(', ')} (from manual selection)`));
1059
+ console.log(chalk.cyan(`Platform(s): ${manualSelection.platforms.join(', ')} (from manual selection)`));
1060
1060
  console.log('');
1061
1061
  } else {
1062
1062
  const platformChoices = [
1063
- { name: `Claude Code ${detectedPlatforms.claude ? chalk.green('( Detected)') : ''}`, value: 'claude' },
1064
- { name: `Codex ${detectedPlatforms.codex ? chalk.green('( Detected)') : ''}`, value: 'codex' },
1063
+ { name: `Claude Code ${detectedPlatforms.claude ? chalk.green('([OK] Detected)') : ''}`, value: 'claude' },
1064
+ { name: `Codex ${detectedPlatforms.codex ? chalk.green('([OK] Detected)') : ''}`, value: 'codex' },
1065
1065
  { name: 'All platforms', value: 'all' }
1066
1066
  ];
1067
1067
 
@@ -1113,20 +1113,20 @@ async function install(options = {}) {
1113
1113
  }
1114
1114
 
1115
1115
  // Step 5.5: Turbo Whisper voice dictation (optional, with interview recommendation)
1116
- console.log(chalk.blue('\n🎤 Voice Dictation Setup'));
1116
+ console.log(chalk.blue('\nVoice Dictation Setup'));
1117
1117
  console.log(chalk.gray('Turbo Whisper enables voice-to-text with local Whisper AI server.\n'));
1118
1118
 
1119
1119
  let turboWhisperChoices = [
1120
- { name: '🖥️ Local (CPU) - Run Whisper server locally', value: 'local' },
1121
- { name: '🚀 Docker (GPU) - Run Whisper in Docker with GPU', value: 'docker' },
1122
- { name: '⏭️ Skip - Install later manually', value: 'skip' }
1120
+ { name: 'Local (CPU) - Run Whisper server locally', value: 'local' },
1121
+ { name: 'Docker (GPU) - Run Whisper in Docker with GPU', value: 'docker' },
1122
+ { name: 'Skip - Install later manually', value: 'skip' }
1123
1123
  ];
1124
1124
 
1125
1125
  // Adjust default based on interview
1126
1126
  let defaultTurboMode = 'skip';
1127
1127
  if (installMode === 'custom' && recommendedTurboWhisper !== 'skip') {
1128
1128
  defaultTurboMode = recommendedTurboWhisper;
1129
- console.log(chalk.cyan(`💡 Recommandation: ${recommendedTurboWhisper === 'docker' ? 'Docker (GPU)' : 'Local (CPU)'} basé sur votre profil\n`));
1129
+ console.log(chalk.cyan(`Recommandation: ${recommendedTurboWhisper === 'docker' ? 'Docker (GPU)' : 'Local (CPU)'} basé sur votre profil\n`));
1130
1130
  }
1131
1131
 
1132
1132
  const { turboWhisperMode } = await inquirer.prompt([
@@ -1188,7 +1188,7 @@ async function install(options = {}) {
1188
1188
  // module dirs keep only their config/help/teams/data).
1189
1189
  const byanSource = path.join(templateDir, '_byan');
1190
1190
 
1191
- // Directories to copy from templates/_byan/ project/_byan/.
1191
+ // Directories to copy from templates/_byan/ -> project/_byan/.
1192
1192
  // Gen3 by-type dirs (agent, workflow, connaissance, command, worker,
1193
1193
  // memoire) plus the retained module config dirs and _config/data.
1194
1194
  const byanDirs = ['agent', 'workflow', 'connaissance', 'command', 'worker', 'memoire',
@@ -1213,7 +1213,7 @@ async function install(options = {}) {
1213
1213
  }
1214
1214
 
1215
1215
  copySpinner.text = 'Copied platform files...';
1216
- console.log(chalk.green(` Platform: _byan/ (agent, workflow, connaissance, command, worker, memoire, config)`));
1216
+ console.log(chalk.green(` [OK] Platform: _byan/ (agent, workflow, connaissance, command, worker, memoire, config)`));
1217
1217
 
1218
1218
  // Copy cost optimizer worker if enabled
1219
1219
  if (interviewAnswers && interviewAnswers.costOptimizer) {
@@ -1226,10 +1226,10 @@ async function install(options = {}) {
1226
1226
  if (await fs.pathExists(workerSource)) {
1227
1227
  await fs.copy(workerSource, workerDest, { overwrite: true });
1228
1228
  copySpinner.text = 'Copied cost optimizer worker...';
1229
- console.log(chalk.green(` Cost Optimizer: ${workerSource} ${workerDest}`));
1230
- console.log(chalk.cyan(' 💰 Automatic LLM cost optimization enabled (~54% savings)'));
1229
+ console.log(chalk.green(` [OK] Cost Optimizer: ${workerSource} -> ${workerDest}`));
1230
+ console.log(chalk.cyan(' Automatic LLM cost optimization enabled (~54% savings)'));
1231
1231
  } else {
1232
- copySpinner.warn(`⚠ Cost optimizer source not found: ${workerSource}`);
1232
+ copySpinner.warn(`[WARN] Cost optimizer source not found: ${workerSource}`);
1233
1233
  }
1234
1234
  }
1235
1235
 
@@ -1251,7 +1251,7 @@ async function install(options = {}) {
1251
1251
  await fs.writeFile(skillPath, skillContent, 'utf8');
1252
1252
  codexCount++;
1253
1253
  }
1254
- console.log(chalk.green(` Codex: ${codexCount} skills .codex/prompts/`));
1254
+ console.log(chalk.green(` [OK] Codex: ${codexCount} skills -> .codex/prompts/`));
1255
1255
  }
1256
1256
 
1257
1257
  // --- CLAUDE: Copy rules + generate agent rules ---
@@ -1262,11 +1262,11 @@ async function install(options = {}) {
1262
1262
  if (await fs.pathExists(claudeSource)) {
1263
1263
  await fs.ensureDir(path.join(claudeDest, 'rules'));
1264
1264
  await fs.copy(claudeSource, claudeDest, { overwrite: true });
1265
- console.log(chalk.green(` Claude Code: CLAUDE.md + rules/ (Hermes, agents, methodology)`));
1265
+ console.log(chalk.green(` [OK] Claude Code: CLAUDE.md + rules/ (Hermes, agents, methodology)`));
1266
1266
  }
1267
1267
  }
1268
1268
 
1269
- console.log(chalk.gray(` Agent roles: dispatcher(hermes), workflow agents, context agents, workers`));
1269
+ console.log(chalk.gray(` [INFO] Agent roles: dispatcher(hermes), workflow agents, context agents, workers`));
1270
1270
 
1271
1271
  } else {
1272
1272
  // AUTO/CUSTOM mode: Copy all platform stubs (existing behavior)
@@ -1280,7 +1280,7 @@ async function install(options = {}) {
1280
1280
  await fs.ensureDir(path.join(claudeDest, 'rules'));
1281
1281
  await fs.copy(claudeSource, claudeDest, { overwrite: true });
1282
1282
  copySpinner.text = 'Copied Claude Code rules + Hermes dispatcher...';
1283
- console.log(chalk.green(` Claude Code: CLAUDE.md + rules/ (Hermes, agents, methodology)`));
1283
+ console.log(chalk.green(` [OK] Claude Code: CLAUDE.md + rules/ (Hermes, agents, methodology)`));
1284
1284
  }
1285
1285
  }
1286
1286
  }
@@ -1313,10 +1313,10 @@ async function install(options = {}) {
1313
1313
  );
1314
1314
  console.log(chalk.gray(' Codex is not covered by this feature.'));
1315
1315
  } catch (error) {
1316
- console.log(chalk.red(` Claude native setup failed: ${error.message}`));
1316
+ console.log(chalk.red(` [ERROR] Claude native setup failed: ${error.message}`));
1317
1317
  console.log(
1318
1318
  chalk.yellow(
1319
- ` MCP, hooks or skills may be incomplete. Inspect _byan/mcp/byan-mcp-server/ and re-run if empty.`
1319
+ ` -> MCP, hooks or skills may be incomplete. Inspect _byan/mcp/byan-mcp-server/ and re-run if empty.`
1320
1320
  )
1321
1321
  );
1322
1322
  }
@@ -1324,14 +1324,14 @@ async function install(options = {}) {
1324
1324
 
1325
1325
  if (needsCodex) {
1326
1326
  console.log();
1327
- console.log(chalk.cyan('Codex CLI MCP setup (~/.codex/config.toml)'));
1327
+ console.log(chalk.cyan('Codex CLI native setup (~/.codex/config.toml + ~/.codex/skills)'));
1328
1328
  try {
1329
- await setupCodexNative(projectRoot);
1329
+ await setupCodexNative(projectRoot, { templateDir, force: true });
1330
1330
  } catch (error) {
1331
- console.log(chalk.red(` Codex MCP setup failed: ${error.message}`));
1331
+ console.log(chalk.red(` [ERROR] Codex native setup failed: ${error.message}`));
1332
1332
  console.log(
1333
1333
  chalk.yellow(
1334
- ` Edit ~/.codex/config.toml manually to add the byan MCP entry.`
1334
+ ` -> Edit ~/.codex/config.toml manually to add the byan MCP entry, then copy BYAN skills into ~/.codex/skills.`
1335
1335
  )
1336
1336
  );
1337
1337
  }
@@ -1383,7 +1383,7 @@ async function install(options = {}) {
1383
1383
  try {
1384
1384
  byanWebResult = await setupByanWebIntegration(projectRoot);
1385
1385
  } catch (error) {
1386
- console.log(chalk.yellow(` byan_web setup skipped: ${error.message}`));
1386
+ console.log(chalk.yellow(` [WARN] byan_web setup skipped: ${error.message}`));
1387
1387
  }
1388
1388
 
1389
1389
  if (byanWebResult && byanWebResult.configured) {
@@ -1393,11 +1393,11 @@ async function install(options = {}) {
1393
1393
  token: byanWebResult.token,
1394
1394
  });
1395
1395
  if (check.reachable && check.status < 400) {
1396
- console.log(chalk.green(` byan_web reachable (${check.latencyMs}ms)`));
1396
+ console.log(chalk.green(` [OK] byan_web reachable (${check.latencyMs}ms)`));
1397
1397
  } else if (check.reachable) {
1398
- console.log(chalk.yellow(` byan_web responded ${check.status} — check token/URL`));
1398
+ console.log(chalk.yellow(` [WARN] byan_web responded ${check.status} — check token/URL`));
1399
1399
  } else {
1400
- console.log(chalk.yellow(` byan_web UNREACHABLE (${check.error})`));
1400
+ console.log(chalk.yellow(` [WARN] byan_web UNREACHABLE (${check.error})`));
1401
1401
  console.log(chalk.gray(` Re-run installer or edit .env / .mcp.json to fix later.`));
1402
1402
  }
1403
1403
  } catch (_) {
@@ -1413,7 +1413,7 @@ async function install(options = {}) {
1413
1413
  byanWebConfigured: true,
1414
1414
  });
1415
1415
  } catch (error) {
1416
- console.log(chalk.yellow(` memory-sync setup skipped: ${error.message}`));
1416
+ console.log(chalk.yellow(` [WARN] memory-sync setup skipped: ${error.message}`));
1417
1417
  }
1418
1418
  }
1419
1419
  }
@@ -1422,37 +1422,58 @@ async function install(options = {}) {
1422
1422
  try {
1423
1423
  await setupMcpExtensions(projectRoot, {});
1424
1424
  } catch (error) {
1425
- console.log(chalk.yellow(` MCP extensions setup skipped: ${error.message}`));
1425
+ console.log(chalk.yellow(` [WARN] MCP extensions setup skipped: ${error.message}`));
1426
1426
  }
1427
1427
  }
1428
1428
 
1429
- if (needsClaude && shouldOfferRtk()) {
1429
+ if ((needsClaude || needsCodex) && shouldOfferRtk()) {
1430
1430
  console.log();
1431
1431
  console.log(chalk.cyan('RTK token optimizer (optional — Rust binary, cuts dev-command tokens 60-90%)'));
1432
1432
  try {
1433
+ const rtkTargets = [
1434
+ ...(needsClaude ? ['claude'] : []),
1435
+ ...(needsCodex ? ['codex'] : []),
1436
+ ];
1437
+ const rtkMessage = needsClaude && needsCodex
1438
+ ? 'Install rtk now? Runs its official installer, adds the GLOBAL Claude Code hook via `rtk init -g --auto-patch`, and makes the native rtk binary available for Codex (no transparent Codex hook).'
1439
+ : needsClaude
1440
+ ? 'Install rtk now? Runs its official installer (brew/cargo, or a pinned curl|sh) and adds a GLOBAL Claude Code hook via `rtk init -g --auto-patch`.'
1441
+ : 'Install rtk now? Runs its official installer (brew/cargo, or a pinned curl|sh) and makes the native rtk binary available for Codex workflows. Codex has no transparent RTK hook here.';
1433
1442
  const { proceed } = await inquirer.prompt([
1434
1443
  {
1435
1444
  type: 'confirm',
1436
1445
  name: 'proceed',
1437
- message: 'Install rtk now? Runs its official installer (brew/cargo, or a pinned curl|sh) and adds a GLOBAL Claude Code hook via `rtk init -g --auto-patch`.',
1446
+ message: rtkMessage,
1438
1447
  default: false,
1439
1448
  },
1440
1449
  ]);
1441
1450
  if (proceed) {
1442
1451
  console.log(chalk.gray(' Installing... progress streams below. The cargo fallback compiles from source (can take minutes); Ctrl+C is safe — BYAN is already installed.'));
1443
- const r = setupRtkIntegration({ log: (m) => console.log(chalk.gray(' ' + m)) });
1452
+ const r = setupRtkIntegration({ targetPlatforms: rtkTargets, log: (m) => console.log(chalk.gray(' ' + m)) });
1444
1453
  if (r.synced) {
1445
- console.log(chalk.green(` ✓ rtk ready (${r.installedVia}, v${r.version || '?'}) — restart Claude Code to activate`));
1446
- if (r.pathHint) console.log(chalk.yellow(` rtk is not on your PATHadd it: ${r.pathHint}`));
1454
+ if (r.claudeHook && r.codexReady) {
1455
+ console.log(chalk.green(` [OK] rtk ready (${r.installedVia}, v${r.version || '?'})restart Claude Code to activate; Codex can use the native rtk binary`));
1456
+ } else if (r.claudeHook) {
1457
+ console.log(chalk.green(` [OK] rtk ready (${r.installedVia}, v${r.version || '?'}) — restart Claude Code to activate`));
1458
+ } else if (r.codexReady) {
1459
+ console.log(chalk.green(` [OK] rtk ready for Codex (${r.installedVia}, v${r.version || '?'}) — native binary installed; no transparent Codex hook`));
1460
+ } else {
1461
+ console.log(chalk.green(` [OK] rtk ready (${r.installedVia}, v${r.version || '?'})`));
1462
+ }
1463
+ if (r.pathHint) console.log(chalk.yellow(` [WARN] rtk is not on your PATH — add it: ${r.pathHint}`));
1447
1464
  } else {
1448
- console.log(chalk.yellow(` ⚠ rtk not wired (${r.reason}) — BYAN unaffected; re-run \`npm run setup-rtk\` anytime`));
1449
- if (r.pathHint) console.log(chalk.yellow(` rtk found off-PATHadd it then re-run: ${r.pathHint}`));
1465
+ if (r.codexReady) {
1466
+ console.log(chalk.yellow(` [WARN] rtk Claude hook not wired (${r.reason}) Codex can still use the native rtk binary; re-run \`npm run setup-rtk\` anytime`));
1467
+ } else {
1468
+ console.log(chalk.yellow(` [WARN] rtk not ready (${r.reason}) — BYAN unaffected; re-run \`npm run setup-rtk\` anytime`));
1469
+ }
1470
+ if (r.pathHint) console.log(chalk.yellow(` [WARN] rtk found off-PATH — add it then re-run: ${r.pathHint}`));
1450
1471
  }
1451
1472
  } else {
1452
1473
  console.log(chalk.gray(' rtk skipped — run `npm run setup-rtk` anytime to enable.'));
1453
1474
  }
1454
1475
  } catch (error) {
1455
- console.log(chalk.yellow(` rtk setup skipped: ${error.message}`));
1476
+ console.log(chalk.yellow(` [WARN] rtk setup skipped: ${error.message}`));
1456
1477
  }
1457
1478
  }
1458
1479
 
@@ -1471,15 +1492,15 @@ async function install(options = {}) {
1471
1492
  if (proceed) {
1472
1493
  const r = await setupGdocPublish({ log: (...a) => console.log(...a) });
1473
1494
  if (r.configured) {
1474
- console.log(chalk.green(` byan_publish prêt (clé : ${r.path})`));
1495
+ console.log(chalk.green(` [OK] byan_publish prêt (clé : ${r.path})`));
1475
1496
  } else {
1476
- console.log(chalk.yellow(` byan_publish non configuré (${r.skipReason}) — \`npm run setup-gdoc\` à tout moment`));
1497
+ console.log(chalk.yellow(` [WARN] byan_publish non configuré (${r.skipReason}) — \`npm run setup-gdoc\` à tout moment`));
1477
1498
  }
1478
1499
  } else {
1479
1500
  console.log(chalk.gray(' byan_publish ignoré — `npm run setup-gdoc` à tout moment pour activer.'));
1480
1501
  }
1481
1502
  } catch (error) {
1482
- console.log(chalk.yellow(` byan_publish setup skipped: ${error.message}`));
1503
+ console.log(chalk.yellow(` [WARN] byan_publish setup skipped: ${error.message}`));
1483
1504
  }
1484
1505
  }
1485
1506
 
@@ -1490,7 +1511,7 @@ async function install(options = {}) {
1490
1511
  try {
1491
1512
  leantimeResult = await setupLeantimeIntegration(projectRoot);
1492
1513
  } catch (error) {
1493
- console.log(chalk.yellow(` Leantime setup skipped: ${error.message}`));
1514
+ console.log(chalk.yellow(` [WARN] Leantime setup skipped: ${error.message}`));
1494
1515
  }
1495
1516
 
1496
1517
  if (leantimeResult && leantimeResult.configured) {
@@ -1500,13 +1521,13 @@ async function install(options = {}) {
1500
1521
  token: leantimeResult.token,
1501
1522
  });
1502
1523
  if (check.reachable && !check.reason) {
1503
- console.log(chalk.green(` Leantime reachable (${check.latencyMs}ms)`));
1524
+ console.log(chalk.green(` [OK] Leantime reachable (${check.latencyMs}ms)`));
1504
1525
  } else if (check.reason === 'non_json') {
1505
- console.log(chalk.yellow(` Leantime responded with non-JSON — ${check.hint}`));
1526
+ console.log(chalk.yellow(` [WARN] Leantime responded with non-JSON — ${check.hint}`));
1506
1527
  } else if (check.reachable) {
1507
- console.log(chalk.yellow(` Leantime responded (${check.reason}) — check URL/token`));
1528
+ console.log(chalk.yellow(` [WARN] Leantime responded (${check.reason}) — check URL/token`));
1508
1529
  } else {
1509
- console.log(chalk.yellow(` Leantime UNREACHABLE (${check.reason})`));
1530
+ console.log(chalk.yellow(` [WARN] Leantime UNREACHABLE (${check.reason})`));
1510
1531
  console.log(chalk.gray(` Re-run installer or edit .env / .mcp.json to fix later.`));
1511
1532
  }
1512
1533
  } catch (_) {
@@ -1761,7 +1782,7 @@ async function install(options = {}) {
1761
1782
  }
1762
1783
 
1763
1784
  if (passed === checks.length) {
1764
- verifySpinner.succeed(`Verification: ${passed}/${checks.length} checks passed ✅`);
1785
+ verifySpinner.succeed(`Verification: ${passed}/${checks.length} checks passed [OK]`);
1765
1786
  } else {
1766
1787
  verifySpinner.warn(`Verification: ${passed}/${checks.length} checks passed`);
1767
1788
  if (failed.length > 0) {
@@ -1773,7 +1794,7 @@ async function install(options = {}) {
1773
1794
  console.log('');
1774
1795
  console.log(chalk.green('╔════════════════════════════════════════════════════════════╗'));
1775
1796
  console.log(chalk.green('║ ║'));
1776
- console.log(chalk.green('║ BYAN INSTALLATION COMPLETE! ║'));
1797
+ console.log(chalk.green('║ [OK] BYAN INSTALLATION COMPLETE! ║'));
1777
1798
  console.log(chalk.green('║ ║'));
1778
1799
  console.log(chalk.green('╚════════════════════════════════════════════════════════════╝'));
1779
1800
  console.log('');
@@ -1792,19 +1813,19 @@ async function install(options = {}) {
1792
1813
 
1793
1814
  if (isManual && manualSelection) {
1794
1815
  console.log(chalk.cyan(`\n Agents Installed (${manualSelection.agents.length}):`));
1795
- console.log(chalk.cyan(` Dispatcher: hermes (always installed)`));
1816
+ console.log(chalk.cyan(` [OK] Dispatcher: hermes (always installed)`));
1796
1817
  const otherAgents = manualSelection.agents.filter(a => a !== 'hermes');
1797
1818
  if (otherAgents.length > 0) {
1798
- console.log(chalk.cyan(` Selected: ${otherAgents.join(', ')}`));
1819
+ console.log(chalk.cyan(` [OK] Selected: ${otherAgents.join(', ')}`));
1799
1820
  }
1800
1821
  }
1801
1822
  if (v2Installed) {
1802
1823
  console.log(chalk.cyan('\n v2.2 Components Installed:'));
1803
- console.log(chalk.cyan(' Core: Context, Cache, Dispatcher, Worker Pool, Workflow'));
1804
- console.log(chalk.cyan(' Model Selector: Intelligent model selection'));
1805
- console.log(chalk.cyan(' Observability: Logger, Metrics, Dashboard'));
1806
- console.log(chalk.cyan(' Tests: 9 test suites with 364 tests'));
1807
- console.log(chalk.cyan(' Entry Point: src/index.js'));
1824
+ console.log(chalk.cyan(' [OK] Core: Context, Cache, Dispatcher, Worker Pool, Workflow'));
1825
+ console.log(chalk.cyan(' [OK] Model Selector: Intelligent model selection'));
1826
+ console.log(chalk.cyan(' [OK] Observability: Logger, Metrics, Dashboard'));
1827
+ console.log(chalk.cyan(' [OK] Tests: 9 test suites with 364 tests'));
1828
+ console.log(chalk.cyan(' [OK] Entry Point: src/index.js'));
1808
1829
  }
1809
1830
 
1810
1831
  console.log('');
@@ -1833,12 +1854,12 @@ async function install(options = {}) {
1833
1854
  if (platform === 'claude') {
1834
1855
  console.log(` ${chalk.blue('claude')}`);
1835
1856
  console.log(` Hermes est integre via ${chalk.cyan('.claude/CLAUDE.md')}`);
1836
- console.log(` Demande: ${chalk.cyan('"quel agent pour mon projet?"')} Hermes repond`);
1857
+ console.log(` Demande: ${chalk.cyan('"quel agent pour mon projet?"')} -> Hermes repond`);
1837
1858
  console.log(` Regles: ${chalk.cyan('.claude/rules/')} (hermes, agents, methodologie)`);
1838
1859
  } else if (platform === 'codex') {
1839
1860
  console.log(` ${chalk.blue('codex')}`);
1840
1861
  console.log(` Skills installes dans ${chalk.cyan('.codex/prompts/')}`);
1841
- console.log(` Lance: ${chalk.cyan('codex skill hermes')} Hermes route vers le bon agent`);
1862
+ console.log(` Lance: ${chalk.cyan('codex skill hermes')} -> Hermes route vers le bon agent`);
1842
1863
  } else {
1843
1864
  console.log(' Follow your platform\'s agent activation procedure');
1844
1865
  }
@@ -1846,13 +1867,13 @@ async function install(options = {}) {
1846
1867
  // Turbo Whisper instructions
1847
1868
  if (turboWhisperInstalled) {
1848
1869
  console.log('');
1849
- console.log(chalk.yellow('🎤 Turbo Whisper Voice Dictation:'));
1870
+ console.log(chalk.yellow('Turbo Whisper Voice Dictation:'));
1850
1871
  console.log('');
1851
1872
 
1852
1873
  if (turboWhisperMode === 'local' || turboWhisperMode === 'docker') {
1853
1874
  console.log(chalk.gray(' Lancement simplifié (1 commande):'));
1854
1875
  console.log(` ${chalk.blue('./scripts/launch-turbo-whisper.sh')}`);
1855
- console.log(chalk.gray(' Démarre automatiquement le serveur si nécessaire'));
1876
+ console.log(chalk.gray(' -> Démarre automatiquement le serveur si nécessaire'));
1856
1877
  console.log('');
1857
1878
  }
1858
1879
 
@@ -1863,7 +1884,7 @@ async function install(options = {}) {
1863
1884
  console.log('');
1864
1885
  console.log(chalk.gray('Need help? Type \'/bmad-help\' when BYAN is active'));
1865
1886
  console.log('');
1866
- console.log(chalk.blue('Happy agent building! 🏗️'));
1887
+ console.log(chalk.blue('Happy agent building! '));
1867
1888
  }
1868
1889
 
1869
1890
  // CLI Program