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
@@ -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
 
@@ -25,6 +25,10 @@ function getCodexConfigPath() {
25
25
  return path.join(os.homedir(), '.codex', 'config.toml');
26
26
  }
27
27
 
28
+ function getCodexSkillsDir() {
29
+ return path.join(os.homedir(), '.codex', 'skills');
30
+ }
31
+
28
32
  async function detectCodex() {
29
33
  return fs.pathExists(path.join(os.homedir(), '.codex'));
30
34
  }
@@ -123,6 +127,81 @@ async function patchCodexConfig(projectRoot, options = {}) {
123
127
  return { path: configPath, hadExisting: existing.length > 0, tokenSet: apiToken.length > 0 };
124
128
  }
125
129
 
130
+ function uniqueExistingDirs(dirs) {
131
+ const seen = new Set();
132
+ const out = [];
133
+ for (const dir of dirs.filter(Boolean)) {
134
+ const resolved = path.resolve(dir);
135
+ if (seen.has(resolved)) continue;
136
+ seen.add(resolved);
137
+ out.push(resolved);
138
+ }
139
+ return out;
140
+ }
141
+
142
+ async function findSkillDirs(sourceDirs = []) {
143
+ const skills = [];
144
+ const seenNames = new Set();
145
+
146
+ for (const sourceDir of uniqueExistingDirs(sourceDirs)) {
147
+ if (!(await fs.pathExists(sourceDir))) continue;
148
+ const entries = await fs.readdir(sourceDir, { withFileTypes: true });
149
+ for (const entry of entries) {
150
+ if (!entry.isDirectory()) continue;
151
+ const skillName = entry.name;
152
+ if (seenNames.has(skillName)) continue;
153
+ const skillDir = path.join(sourceDir, skillName);
154
+ const skillFile = path.join(skillDir, 'SKILL.md');
155
+ if (!(await fs.pathExists(skillFile))) continue;
156
+ seenNames.add(skillName);
157
+ skills.push({ name: skillName, path: skillDir, sourceDir });
158
+ }
159
+ }
160
+
161
+ return skills;
162
+ }
163
+
164
+ function defaultSkillSourceDirs(projectRoot, options = {}) {
165
+ const templateDir = options.templateDir;
166
+ return [
167
+ path.join(projectRoot, '.codex', 'skills'),
168
+ path.join(projectRoot, '.claude', 'skills'),
169
+ templateDir ? path.join(templateDir, '.codex', 'skills') : null,
170
+ templateDir ? path.join(templateDir, '.claude', 'skills') : null,
171
+ ];
172
+ }
173
+
174
+ async function installCodexNativeSkills(projectRoot, options = {}) {
175
+ const destDir = options.destDir || getCodexSkillsDir();
176
+ const sourceDirs = options.sourceDirs || defaultSkillSourceDirs(projectRoot, options);
177
+ const overwrite = options.overwrite !== false;
178
+
179
+ await fs.ensureDir(destDir);
180
+
181
+ const skills = await findSkillDirs(sourceDirs);
182
+ const result = {
183
+ destDir,
184
+ installed: 0,
185
+ skipped: 0,
186
+ skills: [],
187
+ };
188
+
189
+ for (const skill of skills) {
190
+ const dest = path.join(destDir, skill.name);
191
+ const exists = await fs.pathExists(dest);
192
+ if (exists && !overwrite) {
193
+ result.skipped++;
194
+ result.skills.push({ name: skill.name, status: 'skipped-existing', path: dest });
195
+ continue;
196
+ }
197
+ await fs.copy(skill.path, dest, { overwrite: true, errorOnExist: false });
198
+ result.installed++;
199
+ result.skills.push({ name: skill.name, status: exists ? 'updated' : 'installed', path: dest });
200
+ }
201
+
202
+ return result;
203
+ }
204
+
126
205
  async function setupCodexNative(projectRoot, options = {}) {
127
206
  const log = options.quiet ? () => {} : (...a) => console.log(...a);
128
207
 
@@ -133,24 +212,37 @@ async function setupCodexNative(projectRoot, options = {}) {
133
212
  }
134
213
 
135
214
  const result = await patchCodexConfig(projectRoot, options);
136
- log(chalk.green(` βœ“ Codex MCP entry written to ${result.path}`));
215
+ log(chalk.green(` [OK] Codex MCP entry written to ${result.path}`));
137
216
  if (!result.tokenSet) {
138
217
  log(
139
218
  chalk.yellow(
140
- ` ⚠ 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`
141
220
  )
142
221
  );
143
222
  log(chalk.gray(' (or rerun with BYAN_API_TOKEN=byan_xxx in the env)'));
144
223
  }
145
- log(chalk.gray(' Restart Codex CLI for the new MCP server to load'));
146
- return result;
224
+ const skills = await installCodexNativeSkills(projectRoot, options);
225
+ if (skills.installed > 0) {
226
+ log(chalk.green(` [OK] Codex native skills installed to ${skills.destDir} (${skills.installed})`));
227
+ } else {
228
+ log(chalk.yellow(` ! No Codex native skills found to install into ${skills.destDir}`));
229
+ }
230
+ if (skills.skipped > 0) {
231
+ log(chalk.gray(` ${skills.skipped} existing skill(s) skipped`));
232
+ }
233
+ log(chalk.gray(' Restart Codex CLI for the new MCP server and skills to load'));
234
+ return { ...result, skills };
147
235
  }
148
236
 
149
237
  module.exports = {
150
238
  setupCodexNative,
151
239
  patchCodexConfig,
240
+ installCodexNativeSkills,
241
+ findSkillDirs,
242
+ defaultSkillSourceDirs,
152
243
  stripServerSections,
153
244
  buildByanBlock,
154
245
  getCodexConfigPath,
246
+ getCodexSkillsDir,
155
247
  detectCodex,
156
248
  };
@@ -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, Idea→Code, 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