create-byan-agent 2.42.0 → 2.45.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 (71) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/install/bin/byan-kanban.js +1 -1
  3. package/install/bin/create-byan-agent-v2.js +111 -111
  4. package/install/lib/byan-leantime-integration.js +2 -2
  5. package/install/lib/byan-web-integration.js +5 -5
  6. package/install/lib/claude-native-setup.js +11 -11
  7. package/install/lib/codex-native-setup.js +3 -3
  8. package/install/lib/exchange/agent-packager.js +1 -1
  9. package/install/lib/mcp-extensions/gdrive.js +5 -5
  10. package/install/lib/mcp-extensions/index.js +5 -5
  11. package/install/lib/phase2-chat.js +21 -21
  12. package/install/lib/platforms/claude-code.js +2 -2
  13. package/install/lib/project-agents-generator.js +4 -4
  14. package/install/lib/staging-consent.js +1 -1
  15. package/install/lib/subagent-generator.js +2 -3
  16. package/install/lib/utils/logger.js +4 -4
  17. package/install/lib/utils/node-detector.js +1 -1
  18. package/install/lib/yanstaller/agent-launcher.js +1 -1
  19. package/install/lib/yanstaller/index.js +11 -116
  20. package/install/lib/yanstaller/platform-selector.js +11 -11
  21. package/install/src/byan-v2/dispatcher/task-router.js +1 -1
  22. package/install/src/index.js +1 -1
  23. package/install/src/webui/api.js +0 -13
  24. package/install/src/webui/chat/bridge.js +1 -1
  25. package/install/src/webui/chat/cli-detector.js +1 -1
  26. package/install/templates/.claude/CLAUDE.md +1 -0
  27. package/install/templates/.claude/hooks/inject-voice-anchor.js +20 -1
  28. package/install/templates/.claude/hooks/lib/plain-language.js +155 -0
  29. package/install/templates/.claude/hooks/plain-language-check.js +53 -0
  30. package/install/templates/.claude/rules/native-workflows.md +22 -14
  31. package/install/templates/.claude/rules/plain-language.md +73 -0
  32. package/install/templates/.claude/settings.json +4 -0
  33. package/install/templates/_byan/COMPLETION-REPORT.md +0 -1
  34. package/install/templates/_byan/agent/byan/byan-tao.md +12 -0
  35. package/install/templates/_byan/core/activation/soul-activation.md +3 -3
  36. package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-lint-workflows.js +6 -3
  37. package/install/templates/_byan/mcp/byan-mcp-server/lib/native-tiers.js +35 -17
  38. package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-lint.js +38 -0
  39. package/install/templates/_byan/mcp/byan-mcp-server/server.js +37 -0
  40. package/install/templates/_byan/worker/workers.md +1 -1
  41. package/install/templates/_byan/workflow/simple/byan/data/mantras.yaml +15 -4
  42. package/package.json +1 -1
  43. package/src/byan-v2/dispatcher/task-router.js +1 -1
  44. package/src/byan-v2/lib/layout-resolver.js +3 -6
  45. package/install/lib/yanstaller/installer.js +0 -138
  46. package/install/lib/yanstaller/interviewer.js +0 -88
  47. package/install/lib/yanstaller/recommender.js +0 -102
  48. package/install/lib/yanstaller/troubleshooter.js +0 -89
  49. package/install/lib/yanstaller/validator.js +0 -198
  50. package/install/lib/yanstaller/wizard.js +0 -109
  51. package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
  52. package/install/src/byan-v2/dispatcher/task-tool-interface.js +0 -123
  53. package/install/templates/_bmad/bmb/agents/agent-builder.md +0 -59
  54. package/install/templates/_bmad/bmb/agents/byan-test.md +0 -116
  55. package/install/templates/_bmad/bmb/agents/byan.md +0 -215
  56. package/install/templates/_bmad/bmb/agents/marc.md +0 -303
  57. package/install/templates/_bmad/bmb/agents/module-builder.md +0 -60
  58. package/install/templates/_bmad/bmb/agents/patnote.md +0 -495
  59. package/install/templates/_bmad/bmb/agents/rachid.md +0 -184
  60. package/install/templates/_bmad/bmb/agents/workflow-builder.md +0 -61
  61. package/install/templates/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -272
  62. package/install/templates/_bmad/bmb/workflows/byan/data/templates.yaml +0 -59
  63. package/install/templates/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -657
  64. package/install/templates/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -688
  65. package/install/templates/_bmad/bmb/workflows/byan/interview-workflow.md +0 -753
  66. package/install/templates/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -450
  67. package/install/templates/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -79
  68. package/install/templates/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -676
  69. package/install/templates/_bmad/core/agents/carmack.md +0 -238
  70. package/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
  71. package/src/byan-v2/dispatcher/task-tool-interface.js +0 -123
@@ -55,7 +55,7 @@ async function setupLeantimeIntegration(projectRoot, options = {}) {
55
55
  if (!options.quiet) {
56
56
  console.log(
57
57
  chalk.gray(
58
- ' Leantime board sync skipped. Re-run installer or edit .env / .claude/settings.local.json to enable later.'
58
+ ' [INFO] Leantime board sync skipped. Re-run installer or edit .env / .claude/settings.local.json to enable later.'
59
59
  )
60
60
  );
61
61
  }
@@ -78,7 +78,7 @@ async function setupLeantimeIntegration(projectRoot, options = {}) {
78
78
  const mcpPath = mcpResult.path;
79
79
 
80
80
  if (!options.quiet) {
81
- console.log(chalk.green(' Leantime board sync configured'));
81
+ console.log(chalk.green(' [OK] Leantime board sync configured'));
82
82
  console.log(chalk.gray(` - Token (Claude Code) -> ${path.relative(projectRoot, settingsPath)}`));
83
83
  console.log(chalk.gray(` - Token (shell / env) -> ${path.relative(projectRoot, envPath)}`));
84
84
  console.log(chalk.gray(` - Refs (\${LEANTIME_*}) -> ${path.relative(projectRoot, mcpPath)}`));
@@ -45,7 +45,7 @@ async function setupByanWebIntegration(projectRoot, options = {}) {
45
45
  if (!options.quiet) {
46
46
  console.log(
47
47
  chalk.gray(
48
- ' byan_web integration skipped. Re-run installer or edit .env / .claude/settings.local.json to enable later.'
48
+ ' [INFO] byan_web integration skipped. Re-run installer or edit .env / .claude/settings.local.json to enable later.'
49
49
  )
50
50
  );
51
51
  }
@@ -63,11 +63,11 @@ async function setupByanWebIntegration(projectRoot, options = {}) {
63
63
  const credsResult = await sharedWriteCredentials({ BYAN_API_URL: stripApiSuffix(inputs.apiUrl), BYAN_API_TOKEN: inputs.token });
64
64
 
65
65
  if (!options.quiet) {
66
- console.log(chalk.green(` byan_web integration configured`));
67
- console.log(chalk.gray(` - Token (Claude Code) ${path.relative(projectRoot, settingsPath)}`));
68
- console.log(chalk.gray(` - Token (shell / env) ${path.relative(projectRoot, envPath)}`));
66
+ console.log(chalk.green(` [OK] byan_web integration configured`));
67
+ console.log(chalk.gray(` - Token (Claude Code) -> ${path.relative(projectRoot, settingsPath)}`));
68
+ console.log(chalk.gray(` - Token (shell / env) -> ${path.relative(projectRoot, envPath)}`));
69
69
  console.log(chalk.gray(` - MCP server registered in ${path.relative(projectRoot, mcpPath)}`));
70
- console.log(chalk.gray(` - MCP credentials (all shells/OS) ${credsResult.path}`));
70
+ console.log(chalk.gray(` - MCP credentials (all shells/OS) -> ${credsResult.path}`));
71
71
  }
72
72
 
73
73
  return {
@@ -151,23 +151,23 @@ async function setupClaudeNative(projectRoot, options = {}) {
151
151
  const results = {};
152
152
 
153
153
  results.hooks = await copyClaudeHooks(projectRoot);
154
- log(chalk.green(` Claude Code hooks: ${results.hooks.copied} files`));
154
+ log(chalk.green(` [OK] Claude Code hooks: ${results.hooks.copied} files`));
155
155
 
156
156
  results.skills = await copyClaudeSkills(projectRoot);
157
- log(chalk.green(` Claude Code skills: ${results.skills.copied} skills`));
157
+ log(chalk.green(` [OK] Claude Code skills: ${results.skills.copied} skills`));
158
158
 
159
159
  results.settings = await copyClaudeSettings(projectRoot);
160
160
  log(
161
161
  results.settings.copied
162
- ? chalk.green(` Claude Code settings.json (hooks wired)`)
163
- : chalk.yellow(` settings.json template absent`)
162
+ ? chalk.green(` [OK] Claude Code settings.json (hooks wired)`)
163
+ : chalk.yellow(` [WARN] settings.json template absent`)
164
164
  );
165
165
 
166
166
  results.mcp = await copyMcpServer(projectRoot);
167
167
  log(
168
168
  results.mcp.copied
169
- ? chalk.green(` MCP server copied to _byan/mcp/byan-mcp-server/`)
170
- : chalk.yellow(` MCP server template absent`)
169
+ ? chalk.green(` [OK] MCP server copied to _byan/mcp/byan-mcp-server/`)
170
+ : chalk.yellow(` [WARN] MCP server template absent`)
171
171
  );
172
172
 
173
173
  results.mcpConfig = await generateMcpConfig(projectRoot, options);
@@ -180,18 +180,18 @@ async function setupClaudeNative(projectRoot, options = {}) {
180
180
 
181
181
  results.gitHooks = await copyGitHooks(projectRoot);
182
182
  if (results.gitHooks.copied && results.gitHooks.hooksPath) {
183
- log(chalk.green(` Strict pre-commit gate wired (.githooks + core.hooksPath)`));
183
+ log(chalk.green(` [OK] Strict pre-commit gate wired (.githooks + core.hooksPath)`));
184
184
  } else if (results.gitHooks.copied) {
185
- log(chalk.yellow(` .githooks copied but not wired (${results.gitHooks.reason || 'no git repo'}); run: git config core.hooksPath .githooks`));
185
+ log(chalk.yellow(` [WARN] .githooks copied but not wired (${results.gitHooks.reason || 'no git repo'}); run: git config core.hooksPath .githooks`));
186
186
  }
187
187
 
188
188
  if (results.mcp.copied && options.installDeps !== false) {
189
189
  results.mcpDeps = await installMcpDependencies(results.mcp.path);
190
190
  if (results.mcpDeps.installed) {
191
- log(chalk.green(` MCP dependencies installed (npm install)`));
191
+ log(chalk.green(` [OK] MCP dependencies installed (npm install)`));
192
192
  } else {
193
- log(chalk.yellow(` MCP npm install failed: ${results.mcpDeps.error}`));
194
- log(chalk.yellow(` Run manually: cd _byan/mcp/byan-mcp-server && npm install`));
193
+ log(chalk.yellow(` [WARN] MCP npm install failed: ${results.mcpDeps.error}`));
194
+ log(chalk.yellow(` -> Run manually: cd _byan/mcp/byan-mcp-server && npm install`));
195
195
  }
196
196
  }
197
197
 
@@ -212,18 +212,18 @@ async function setupCodexNative(projectRoot, options = {}) {
212
212
  }
213
213
 
214
214
  const result = await patchCodexConfig(projectRoot, options);
215
- log(chalk.green(` Codex MCP entry written to ${result.path}`));
215
+ log(chalk.green(` [OK] Codex MCP entry written to ${result.path}`));
216
216
  if (!result.tokenSet) {
217
217
  log(
218
218
  chalk.yellow(
219
- ` BYAN_API_TOKEN left empty. Edit ${result.path} and set BYAN_API_TOKEN`
219
+ ` [WARN] BYAN_API_TOKEN left empty. Edit ${result.path} and set BYAN_API_TOKEN`
220
220
  )
221
221
  );
222
222
  log(chalk.gray(' (or rerun with BYAN_API_TOKEN=byan_xxx in the env)'));
223
223
  }
224
224
  const skills = await installCodexNativeSkills(projectRoot, options);
225
225
  if (skills.installed > 0) {
226
- log(chalk.green(` Codex native skills installed to ${skills.destDir} (${skills.installed})`));
226
+ log(chalk.green(` [OK] Codex native skills installed to ${skills.destDir} (${skills.installed})`));
227
227
  } else {
228
228
  log(chalk.yellow(` ! No Codex native skills found to install into ${skills.destDir}`));
229
229
  }
@@ -156,7 +156,7 @@ class AgentPackager {
156
156
  async _findAgentFile(name) {
157
157
  // Layout resolver: Gen3 _byan/agent/<name>/ first, then Gen2 flat
158
158
  // _byan/agents/, Gen2 per-module _byan/<module>/agents/ (previously NOT
159
- // searched — agents like dev/analyst live there), then Gen1 _bmad/.
159
+ // searched — agents like dev/analyst live there).
160
160
  const hit = layoutResolver.resolveAgent(name, { projectRoot: this.projectRoot });
161
161
  if (hit) return hit.path;
162
162
 
@@ -97,7 +97,7 @@ function printSetupGuide(log) {
97
97
  log(chalk.cyan('Étapes Google Cloud (faire dans le navigateur, dans cet ordre) :'));
98
98
  SETUP_LINKS.forEach((s, i) => {
99
99
  log(chalk.gray(` ${i + 1}. ${s.step}`));
100
- log(chalk.gray(` ${s.url}`));
100
+ log(chalk.gray(` -> ${s.url}`));
101
101
  });
102
102
  log();
103
103
  log(chalk.gray(` 5. Télécharger le JSON OAuth Client (bouton "Download JSON")`));
@@ -109,8 +109,8 @@ function printSetupGuide(log) {
109
109
  // (all gw scopes qualify) ; "Internal" does not, and skips Google app
110
110
  // verification. Source: developers.google.com/identity/protocols/oauth2.
111
111
  log(chalk.yellow(' Durabilité — LE point qui compte :'));
112
- log(chalk.yellow(' Écran de consentement en "Internal" credential pérenne (token qui ne meurt pas).'));
113
- log(chalk.yellow(' "External + Testing" refresh token expiré sous ~7 jours (scopes hors openid/email/profile, donc tous ceux de gw). À éviter.'));
112
+ log(chalk.yellow(' Écran de consentement en "Internal" -> credential pérenne (token qui ne meurt pas).'));
113
+ log(chalk.yellow(' "External + Testing" -> refresh token expiré sous ~7 jours (scopes hors openid/email/profile, donc tous ceux de gw). À éviter.'));
114
114
  log(chalk.gray(' Limite "Internal" : seuls les comptes de ton org Workspace peuvent autoriser, et il faut UN login navigateur au premier setup.'));
115
115
  log(chalk.gray(' Ce client OAuth devient LE credential Google unique de byan (le connecteur claude.ai Drive devient redondant).'));
116
116
  log();
@@ -143,7 +143,7 @@ async function importCredentialsFromPath(srcPath, log) {
143
143
  await fs.writeFile(CREDENTIALS_PATH, JSON.stringify(parsed, null, 2), {
144
144
  mode: 0o600,
145
145
  });
146
- log(chalk.green(` credentials.json copié vers ${CREDENTIALS_PATH} (perm 600)`));
146
+ log(chalk.green(` [OK] credentials.json copié vers ${CREDENTIALS_PATH} (perm 600)`));
147
147
  }
148
148
 
149
149
  async function runOAuthFlow(log) {
@@ -170,7 +170,7 @@ async function runOAuthFlow(log) {
170
170
  if (result.status !== 0) {
171
171
  throw new Error(`google-workspace-mcp accounts add a échoué (exit ${result.status})`);
172
172
  }
173
- log(chalk.green(` Compte "${accountName}" ajouté`));
173
+ log(chalk.green(` [OK] Compte "${accountName}" ajouté`));
174
174
  return accountName;
175
175
  }
176
176
 
@@ -105,14 +105,14 @@ async function setupMcpExtensions(projectRoot, options = {}) {
105
105
  try {
106
106
  setupResult = await ext.setup({ projectRoot, quiet: options.quiet });
107
107
  } catch (err) {
108
- log(chalk.red(` ${ext.id} setup failed: ${err.message}`));
108
+ log(chalk.red(` [ERROR] ${ext.id} setup failed: ${err.message}`));
109
109
  results.push({ id: ext.id, configured: false, message: `setup error: ${err.message}` });
110
110
  continue;
111
111
  }
112
112
 
113
113
  if (!setupResult || setupResult.configured !== true) {
114
114
  const reason = (setupResult && (setupResult.skipReason || setupResult.message)) || 'setup not completed';
115
- log(chalk.yellow(` ${ext.id}: ${reason}`));
115
+ log(chalk.yellow(` [WARN] ${ext.id}: ${reason}`));
116
116
  results.push({ id: ext.id, configured: false, message: reason });
117
117
  continue;
118
118
  }
@@ -121,7 +121,7 @@ async function setupMcpExtensions(projectRoot, options = {}) {
121
121
  try {
122
122
  entry = await ext.buildMcpEntry({ projectRoot });
123
123
  } catch (err) {
124
- log(chalk.red(` ${ext.id} buildMcpEntry failed: ${err.message}`));
124
+ log(chalk.red(` [ERROR] ${ext.id} buildMcpEntry failed: ${err.message}`));
125
125
  results.push({ id: ext.id, configured: false, message: `buildMcpEntry error: ${err.message}` });
126
126
  continue;
127
127
  }
@@ -129,10 +129,10 @@ async function setupMcpExtensions(projectRoot, options = {}) {
129
129
  try {
130
130
  await addMcpEntry(projectRoot, ext.id, entry);
131
131
  await whitelistMcpServer(projectRoot, ext.id);
132
- log(chalk.green(` ${ext.id} registered in .mcp.json`));
132
+ log(chalk.green(` [OK] ${ext.id} registered in .mcp.json`));
133
133
  results.push({ id: ext.id, configured: true, message: 'registered' });
134
134
  } catch (err) {
135
- log(chalk.red(` ${ext.id} addMcpEntry failed: ${err.message}`));
135
+ log(chalk.red(` [ERROR] ${ext.id} addMcpEntry failed: ${err.message}`));
136
136
  results.push({ id: ext.id, configured: false, message: `addMcpEntry error: ${err.message}` });
137
137
  }
138
138
  }
@@ -92,24 +92,24 @@ function generatePhase2Preprompt(context) {
92
92
 
93
93
  ## Écosystème BYAN - Agents Disponibles
94
94
 
95
- ### 🏛️ Hermes - Dispatcher Universel (NOUVEAU v2.3.2)
95
+ ### Hermes - Dispatcher Universel (NOUVEAU v2.3.2)
96
96
  **Point d'entrée intelligent vers tout l'écosystème BYAN**
97
97
  - **Rôle**: Router intelligent + Agent directory + Pipeline orchestrator
98
98
  - **Invocation**: \`@hermes\`
99
99
  - **Capabilities**:
100
100
  - [LA] Liste 35+ agents par module (core, bmm, bmb, cis, tea)
101
- - [REC] Smart routing: décris ta tâche Hermes recommande les meilleurs agents
102
- - [PIPE] Pipelines multi-agents (Feature Complete, Bug Fix, IdeaCode, etc.)
101
+ - [REC] Smart routing: décris ta tâche -> Hermes recommande les meilleurs agents
102
+ - [PIPE] Pipelines multi-agents (Feature Complete, Bug Fix, Idea->Code, etc.)
103
103
  - [@agent] Invocation directe d'agents
104
104
  - [?agent] Quick help sans charger l'agent
105
105
  - **Quand recommander Hermes**: Toujours! C'est le meilleur point de départ pour découvrir et utiliser les agents BYAN.
106
106
 
107
- ### 📦 Core Module (Foundation)
107
+ ### Core Module (Foundation)
108
108
  - **bmad-master**: Executor & Orchestrator (workflows, tasks)
109
109
  - **yanstaller**: Smart installer (c'est moi!)
110
110
  - **expert-merise-agile**: Conception Merise Agile + MCD/MCT
111
111
 
112
- ### 🔨 BMB Module (Builders)
112
+ ### BMB Module (Builders)
113
113
  - **byan**: Agent creator via interview (12 questions, 64 mantras)
114
114
  - **byan-v2**: Optimized BYAN v2
115
115
  - **agent-builder**: Construction expert
@@ -117,7 +117,7 @@ function generatePhase2Preprompt(context) {
117
117
  - **carmack**: Token optimizer
118
118
  - **patnote**: Update manager
119
119
 
120
- ### 💼 BMM Module (Management - SDLC)
120
+ ### BMM Module (Management - SDLC)
121
121
  - **analyst** (Mary): Business analysis, market research
122
122
  - **architect** (Winston): System design, tech stack
123
123
  - **dev** (Amelia): Implementation, coding
@@ -128,7 +128,7 @@ function generatePhase2Preprompt(context) {
128
128
  - **ux-designer** (Sally): UX/UI design
129
129
  - **quick-flow-solo-dev** (Barry): Fast brownfield dev
130
130
 
131
- ### 🎨 CIS Module (Creative & Innovation)
131
+ ### CIS Module (Creative & Innovation)
132
132
  - **brainstorming-coach** (Carson): Ideation sessions
133
133
  - **creative-problem-solver** (Dr. Quinn): Problem solving
134
134
  - **design-thinking-coach** (Maya): Design thinking
@@ -136,18 +136,18 @@ function generatePhase2Preprompt(context) {
136
136
  - **presentation-master** (Caravaggio): Presentations, slides
137
137
  - **storyteller** (Sophia): Storytelling, narratives
138
138
 
139
- ### 🧪 TEA Module (Testing)
139
+ ### TEA Module (Testing)
140
140
  - **tea** (Murat): Master test architect (ATDD, NFR, CI/CD)
141
141
 
142
142
  ## Workflows Prédéfinis (via Hermes)
143
143
 
144
- 1. **Feature Complete**: PM Architect UX SM Dev Tea
145
- 2. **Idea to Code**: PM Architect SM Quick Flow
144
+ 1. **Feature Complete**: PM -> Architect -> UX -> SM -> Dev -> Tea
145
+ 2. **Idea to Code**: PM -> Architect -> SM -> Quick Flow
146
146
  3. **New Agent**: BYAN (handles entire flow)
147
- 4. **Refactoring**: Architect Dev Tea
148
- 5. **Bug Fix**: Dev Quinn
149
- 6. **Documentation**: Analyst Tech Writer
150
- 7. **Quality Complete**: Tea Quinn code-review
147
+ 4. **Refactoring**: Architect -> Dev -> Tea
148
+ 5. **Bug Fix**: Dev -> Quinn
149
+ 6. **Documentation**: Analyst -> Tech Writer
150
+ 7. **Quality Complete**: Tea -> Quinn -> code-review
151
151
 
152
152
  ## Instructions
153
153
 
@@ -210,17 +210,17 @@ Continue la conversation pour comprendre le projet et personnaliser les agents.`
210
210
  }
211
211
  } catch (error) {
212
212
  const errMsg = (error.message || '').toLowerCase();
213
- console.error(chalk.red(`\n Erreur ${selectedPlatform}: ${error.message}`));
213
+ console.error(chalk.red(`\n[ERROR] Erreur ${selectedPlatform}: ${error.message}`));
214
214
 
215
215
  // Platform-specific login guidance
216
216
  if (selectedPlatform === 'claude' && (errMsg.includes('auth') || errMsg.includes('api') || errMsg.includes('key') || errMsg.includes('login') || errMsg.includes('401'))) {
217
217
  console.log('');
218
- console.log(chalk.yellow(' 💡 Pour se connecter à Claude Code:'));
218
+ console.log(chalk.yellow(' Pour se connecter à Claude Code:'));
219
219
  console.log(chalk.cyan(' 1. claude login'));
220
220
  console.log(chalk.gray(' 2. ou: export ANTHROPIC_API_KEY=sk-ant-...'));
221
221
  console.log(chalk.gray(' 3. ou dans Claude Code: /login'));
222
222
  } else if (selectedPlatform === 'codex') {
223
- console.log(chalk.gray(' codex login'));
223
+ console.log(chalk.gray(' -> codex login'));
224
224
  }
225
225
 
226
226
  result = `Désolé, erreur de communication avec ${selectedPlatform}. Réessayez ou tapez "skip".`;
@@ -271,7 +271,7 @@ async function launchPhase2Chat(options) {
271
271
  console.log('');
272
272
  console.log(chalk.magenta('╔════════════════════════════════════════════════════════════╗'));
273
273
  console.log(chalk.magenta('║') + ' ' + chalk.magenta('║'));
274
- console.log(chalk.magenta('║') + ` ${chalk.bold('💬 PHASE 2 - Conversation Yanstaller')} ` + chalk.magenta('║'));
274
+ console.log(chalk.magenta('║') + ` ${chalk.bold('PHASE 2 - Conversation Yanstaller')} ` + chalk.magenta('║'));
275
275
  console.log(chalk.magenta('║') + ` ${chalk.gray(`Mode interactif - Domaine: ${context.domain}`)} ` + chalk.magenta('║'));
276
276
  console.log(chalk.magenta('║') + ' ' + chalk.magenta('║'));
277
277
  console.log(chalk.magenta('╚════════════════════════════════════════════════════════════╝'));
@@ -281,7 +281,7 @@ async function launchPhase2Chat(options) {
281
281
 
282
282
  // Check if any AI platform is available
283
283
  if (!detectedPlatforms.codex && !detectedPlatforms.claude) {
284
- console.log(chalk.yellow(' Aucune plateforme AI détectée pour le chat.'));
284
+ console.log(chalk.yellow(' [WARN] Aucune plateforme AI détectée pour le chat.'));
285
285
  return null;
286
286
  }
287
287
 
@@ -381,7 +381,7 @@ IMPORTANT: L'utilisateur veut finaliser. Génère maintenant la configuration JS
381
381
  try {
382
382
  const jsonStr = jsonMatch[1] || jsonMatch[0];
383
383
  phase2Config = JSON.parse(jsonStr.trim());
384
- console.log(chalk.green(' Configuration extraite!'));
384
+ console.log(chalk.green(' [OK] Configuration extraite!'));
385
385
  console.log('');
386
386
  continueChat = false;
387
387
  } catch (e) {
@@ -391,7 +391,7 @@ IMPORTANT: L'utilisateur veut finaliser. Génère maintenant la configuration JS
391
391
 
392
392
  // If user wanted to finalize but we didn't get valid JSON
393
393
  if (wantsFinal && !phase2Config) {
394
- console.log(chalk.yellow(' Configuration non générée. Réessayez "finaliser" ou "skip".'));
394
+ console.log(chalk.yellow(' [WARN] Configuration non générée. Réessayez "finaliser" ou "skip".'));
395
395
  console.log('');
396
396
  }
397
397
  }
@@ -103,7 +103,7 @@ async function installViaClaudeAgent(projectRoot, agents, config) {
103
103
 
104
104
  // Check if native launch is available
105
105
  if (agentLauncher.supportsNativeLaunch('claude')) {
106
- logger.info('\n🚀 Launching agent Claude for MCP integration...');
106
+ logger.info('\nLaunching agent Claude for MCP integration...');
107
107
 
108
108
  // Launch agent Claude with create-mcp-server action
109
109
  const result = await agentLauncher.launch({
@@ -125,7 +125,7 @@ async function installViaClaudeAgent(projectRoot, agents, config) {
125
125
  }
126
126
 
127
127
  // Fallback: Manual instructions
128
- logger.info('\n📝 To complete Claude Code integration:');
128
+ logger.info('\nTo complete Claude Code integration:');
129
129
  logger.info(' 1. Run: @bmad-agent-claude');
130
130
  logger.info(' 2. Select option 1: Create MCP server for BYAN agents');
131
131
  logger.info(' 3. Follow the guided setup\n');
@@ -216,10 +216,10 @@ function formatAgentName(name) {
216
216
 
217
217
  function getComplexityBadge(complexity) {
218
218
  switch (complexity) {
219
- case 'simple': return '🟢 Simple (1-2 mantras)';
220
- case 'medium': return '🟡 Medium (3-5 mantras)';
221
- case 'complex': return '🔴 Complex (6+ mantras)';
222
- default: return 'Unknown';
219
+ case 'simple': return 'Simple (1-2 mantras)';
220
+ case 'medium': return 'Medium (3-5 mantras)';
221
+ case 'complex': return 'Complex (6+ mantras)';
222
+ default: return 'Unknown';
223
223
  }
224
224
  }
225
225
 
@@ -6,7 +6,7 @@
6
6
  * memory-sync without credentials is a no-op.
7
7
  *
8
8
  * On opt-in, writes :
9
- * _byan/config.yaml memory_sync: { enabled: true }
9
+ * _byan/config.yaml -> memory_sync: { enabled: true }
10
10
  * OR loadbalancer.yaml if _byan/config.yaml not present
11
11
  *
12
12
  * Prints a clear consent notice listing what gets sent and how to
@@ -16,7 +16,7 @@ const path = require('path');
16
16
  const fs = require('fs');
17
17
 
18
18
  const ROLE_MODEL_MAP = {
19
- // Reasoning-heavy opus
19
+ // Reasoning-heavy -> opus
20
20
  architect: 'opus',
21
21
  'bmm-architect': 'opus',
22
22
  tea: 'opus',
@@ -28,10 +28,9 @@ const ROLE_MODEL_MAP = {
28
28
  'creative-problem-solver': 'opus',
29
29
  'cis-creative-problem-solver': 'opus',
30
30
 
31
- // Narrow mechanical haiku
31
+ // Narrow mechanical -> haiku
32
32
  carmack: 'haiku',
33
33
  rachid: 'haiku',
34
- marc: 'haiku',
35
34
  patnote: 'haiku',
36
35
  drawio: 'haiku',
37
36
  };
@@ -14,7 +14,7 @@ const chalk = require('chalk');
14
14
  * @param {string} message - Message to log
15
15
  */
16
16
  function info(message) {
17
- console.log(chalk.blue(''), message);
17
+ console.log(chalk.blue('[INFO]'), message);
18
18
  }
19
19
 
20
20
  /**
@@ -23,7 +23,7 @@ function info(message) {
23
23
  * @param {string} message - Message to log
24
24
  */
25
25
  function success(message) {
26
- console.log(chalk.green(''), message);
26
+ console.log(chalk.green('[OK]'), message);
27
27
  }
28
28
 
29
29
  /**
@@ -32,7 +32,7 @@ function success(message) {
32
32
  * @param {string} message - Message to log
33
33
  */
34
34
  function warn(message) {
35
- console.log(chalk.yellow(''), message);
35
+ console.log(chalk.yellow('[WARN]'), message);
36
36
  }
37
37
 
38
38
  /**
@@ -41,7 +41,7 @@ function warn(message) {
41
41
  * @param {string} message - Message to log
42
42
  */
43
43
  function error(message) {
44
- console.error(chalk.red(''), message);
44
+ console.error(chalk.red('[ERROR]'), message);
45
45
  }
46
46
 
47
47
  /**
@@ -25,7 +25,7 @@ function detect() {
25
25
  * @returns {number} - -1 if v1 < v2, 0 if equal, 1 if v1 > v2
26
26
  */
27
27
  function compareVersions(version1, version2) {
28
- // Strip suffixes: '18.0.0-beta' '18.0.0'
28
+ // Strip suffixes: '18.0.0-beta' -> '18.0.0'
29
29
  const cleanV1 = version1.replace(/-.*$/, '');
30
30
  const cleanV2 = version2.replace(/-.*$/, '');
31
31
 
@@ -12,7 +12,7 @@ const logger = require('../utils/logger');
12
12
 
13
13
  /**
14
14
  * @typedef {Object} LaunchOptions
15
- * @property {string} agent - Agent name (e.g., 'claude', 'marc')
15
+ * @property {string} agent - Agent name (e.g., 'byan', 'dev')
16
16
  * @property {string} platform - Platform ID (e.g., 'claude', 'codex')
17
17
  * @property {string} [prompt] - Initial prompt/action
18
18
  * @property {string} [model] - Model to use
@@ -1,129 +1,26 @@
1
1
  /**
2
- * YANSTALLER - Main Orchestrator
3
- *
4
- * Coordinates all YANSTALLER modules to perform intelligent BYAN installation.
5
- *
2
+ * YANSTALLER - Backup / update / rollback surface
3
+ *
4
+ * The programmatic install()/uninstall() orchestrator was removed: it was a
5
+ * half-implemented stub (phases 4-9 never wired) and the real installer is
6
+ * install/bin/create-byan-agent-v2.js. What remains here is the live, tested
7
+ * surface consumed by the CLI (update / rollback / backups / check commands)
8
+ * and the web UI: update, rollback, listBackups, plus the raw detector /
9
+ * platformSelector / updater / backuper modules.
10
+ *
6
11
  * @module yanstaller
7
12
  */
8
13
 
9
14
  const path = require('path');
10
15
  const detector = require('./detector');
11
- const recommender = require('./recommender');
12
- const installer = require('./installer');
13
- const validator = require('./validator');
14
- const troubleshooter = require('./troubleshooter');
15
- const interviewer = require('./interviewer');
16
16
  const backuper = require('./backuper');
17
17
  const updater = require('./updater');
18
- const wizard = require('./wizard');
19
18
  const platformSelector = require('./platform-selector');
20
19
  const logger = require('../utils/logger');
21
20
 
22
- /**
23
- * @typedef {Object} YanInstallerOptions
24
- * @property {boolean} [yes] - Skip confirmations (--yes flag)
25
- * @property {string} [mode] - Installation mode: 'full' | 'minimal' | 'custom'
26
- * @property {string[]} [platforms] - Target platforms (override detection)
27
- * @property {boolean} [verbose] - Verbose output
28
- * @property {boolean} [quiet] - Minimal output
29
- */
30
-
31
- /**
32
- * Main installation flow
33
- *
34
- * @param {YanInstallerOptions} [options={}] - Installation options
35
- * @returns {Promise<void>}
36
- */
37
- async function install(options = {}) {
38
- let backupPath = null;
39
-
40
- try {
41
- // Phase 1: Detect environment
42
- logger.info('🔍 Detecting environment...');
43
- const detection = await detector.detect();
44
-
45
- // Phase 2: Validate Node version (FAIL FAST)
46
- if (!detector.isNodeVersionValid(detection.nodeVersion, '18.0.0')) {
47
- throw new Error(`Node.js >= 18.0.0 required. Found: ${detection.nodeVersion}`);
48
- }
49
-
50
- // Phase 3: Platform Selection
51
- let platformSelection;
52
- if (options.platforms) {
53
- // CLI override
54
- platformSelection = {
55
- platforms: options.platforms,
56
- mode: 'manual'
57
- };
58
- } else if (options.yes) {
59
- // Auto mode
60
- platformSelection = {
61
- platforms: detection.platforms.filter(p => p.detected).map(p => p.name),
62
- mode: 'auto'
63
- };
64
- } else {
65
- // Interactive selection
66
- platformSelection = await platformSelector.select(detection);
67
- }
68
-
69
- logger.info(`\n✓ Selected ${platformSelection.platforms.length} platform(s)`);
70
- logger.info(` Mode: ${platformSelection.mode}`);
71
- if (platformSelection.specialist) {
72
- logger.info(` Specialist: @bmad-agent-${platformSelection.specialist}`);
73
- }
74
-
75
- // Phase 4: Recommend configuration
76
- // TODO: Implement
77
-
78
- // Phase 5: Run interview (unless --yes)
79
- // TODO: Implement
80
-
81
- // Phase 6: Backup existing installation
82
- // backupPath = await backuper.backup('_bmad');
83
-
84
- // Phase 7: Install agents
85
- // TODO: Implement
86
-
87
- // Phase 8: Validate installation
88
- // TODO: Implement
89
-
90
- // Phase 9: Show post-install wizard
91
- // TODO: Implement
92
- } catch (error) {
93
- // ROLLBACK STRATEGY: Leave partial state + clear message
94
- // Rationale (Mantra #37 Ockham's Razor):
95
- // - Installation = mostly file copies (low risk)
96
- // - User can re-run (idempotent)
97
- // - Backup exists for manual restore
98
- // - Auto-rollback risks losing working partial install
99
-
100
- logger.error('Installation failed:', error.message);
101
-
102
- if (backupPath) {
103
- logger.info('\nPartial installation completed.');
104
- logger.info(`Backup available at: ${backupPath}`);
105
- logger.info('\nOptions:');
106
- logger.info('1. Re-run: npx create-byan-agent');
107
- logger.info(`2. Restore backup: yanstaller restore ${backupPath}`);
108
- logger.info('3. Troubleshoot: yanstaller doctor');
109
- }
110
-
111
- throw error; // Re-throw for exit code handling
112
- }
113
- }
114
-
115
- /**
116
- * Uninstall BYAN
117
- *
118
- * @returns {Promise<void>}
119
- */
120
- async function uninstall() {
121
- // TODO: Remove _bmad/, .github/agents/ stubs
122
- }
123
-
124
21
  /**
125
22
  * Update existing BYAN installation
126
- *
23
+ *
127
24
  * @param {string} projectRoot - Project root directory
128
25
  * @param {Object} [options={}] - Update options
129
26
  * @param {boolean} [options.force] - Force update even if same version
@@ -163,12 +60,10 @@ async function listBackups(projectRoot) {
163
60
  }
164
61
 
165
62
  module.exports = {
166
- install,
167
- uninstall,
168
63
  update,
169
64
  rollback,
170
65
  listBackups,
171
- // Expose for testing
66
+ // Raw modules exposed for the CLI, the web UI, and tests
172
67
  detector,
173
68
  platformSelector,
174
69
  updater,