create-byan-agent 2.42.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.
- package/CHANGELOG.md +93 -0
- package/install/bin/byan-kanban.js +1 -1
- package/install/bin/create-byan-agent-v2.js +111 -111
- package/install/lib/byan-leantime-integration.js +2 -2
- package/install/lib/byan-web-integration.js +5 -5
- package/install/lib/claude-native-setup.js +11 -11
- package/install/lib/codex-native-setup.js +3 -3
- package/install/lib/exchange/agent-packager.js +1 -1
- package/install/lib/mcp-extensions/gdrive.js +5 -5
- package/install/lib/mcp-extensions/index.js +5 -5
- package/install/lib/phase2-chat.js +21 -21
- package/install/lib/platforms/claude-code.js +2 -2
- package/install/lib/project-agents-generator.js +4 -4
- package/install/lib/staging-consent.js +1 -1
- package/install/lib/subagent-generator.js +2 -3
- package/install/lib/utils/logger.js +4 -4
- package/install/lib/utils/node-detector.js +1 -1
- package/install/lib/yanstaller/agent-launcher.js +1 -1
- package/install/lib/yanstaller/index.js +11 -116
- package/install/lib/yanstaller/platform-selector.js +11 -11
- package/install/src/byan-v2/dispatcher/task-router.js +1 -1
- package/install/src/index.js +1 -1
- package/install/src/webui/api.js +0 -13
- package/install/src/webui/chat/bridge.js +1 -1
- package/install/src/webui/chat/cli-detector.js +1 -1
- package/install/templates/.claude/rules/native-workflows.md +22 -14
- package/install/templates/_byan/COMPLETION-REPORT.md +0 -1
- package/install/templates/_byan/core/activation/soul-activation.md +3 -3
- package/install/templates/_byan/mcp/byan-mcp-server/bin/byan-lint-workflows.js +6 -3
- package/install/templates/_byan/mcp/byan-mcp-server/lib/native-tiers.js +35 -17
- package/install/templates/_byan/mcp/byan-mcp-server/lib/workflows-lint.js +38 -0
- package/install/templates/_byan/worker/workers.md +1 -1
- package/package.json +1 -1
- package/src/byan-v2/dispatcher/task-router.js +1 -1
- package/src/byan-v2/lib/layout-resolver.js +3 -6
- package/install/lib/yanstaller/installer.js +0 -138
- package/install/lib/yanstaller/interviewer.js +0 -88
- package/install/lib/yanstaller/recommender.js +0 -102
- package/install/lib/yanstaller/troubleshooter.js +0 -89
- package/install/lib/yanstaller/validator.js +0 -198
- package/install/lib/yanstaller/wizard.js +0 -109
- package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
- package/install/src/byan-v2/dispatcher/task-tool-interface.js +0 -123
- package/install/templates/_bmad/bmb/agents/agent-builder.md +0 -59
- package/install/templates/_bmad/bmb/agents/byan-test.md +0 -116
- package/install/templates/_bmad/bmb/agents/byan.md +0 -215
- package/install/templates/_bmad/bmb/agents/marc.md +0 -303
- package/install/templates/_bmad/bmb/agents/module-builder.md +0 -60
- package/install/templates/_bmad/bmb/agents/patnote.md +0 -495
- package/install/templates/_bmad/bmb/agents/rachid.md +0 -184
- package/install/templates/_bmad/bmb/agents/workflow-builder.md +0 -61
- package/install/templates/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -272
- package/install/templates/_bmad/bmb/workflows/byan/data/templates.yaml +0 -59
- package/install/templates/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -657
- package/install/templates/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -688
- package/install/templates/_bmad/bmb/workflows/byan/interview-workflow.md +0 -753
- package/install/templates/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -450
- package/install/templates/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -79
- package/install/templates/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -676
- package/install/templates/_bmad/core/agents/carmack.md +0 -238
- package/src/byan-v2/dispatcher/task-tool-interface-mock.js +0 -134
- 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
|
-
'
|
|
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('
|
|
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
|
-
'
|
|
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(`
|
|
67
|
-
console.log(chalk.gray(` - Token (Claude Code)
|
|
68
|
-
console.log(chalk.gray(` - Token (shell / env)
|
|
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)
|
|
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(`
|
|
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(`
|
|
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(`
|
|
163
|
-
: chalk.yellow(`
|
|
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(`
|
|
170
|
-
: chalk.yellow(`
|
|
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(`
|
|
183
|
+
log(chalk.green(` [OK] Strict pre-commit gate wired (.githooks + core.hooksPath)`));
|
|
184
184
|
} else if (results.gitHooks.copied) {
|
|
185
|
-
log(chalk.yellow(`
|
|
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(`
|
|
191
|
+
log(chalk.green(` [OK] MCP dependencies installed (npm install)`));
|
|
192
192
|
} else {
|
|
193
|
-
log(chalk.yellow(`
|
|
194
|
-
log(chalk.yellow(`
|
|
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(`
|
|
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
|
-
`
|
|
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(`
|
|
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)
|
|
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(`
|
|
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"
|
|
113
|
-
log(chalk.yellow(' "External + Testing"
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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(`
|
|
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
|
-
###
|
|
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
|
|
102
|
-
- [PIPE] Pipelines multi-agents (Feature Complete, Bug Fix, Idea
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
|
145
|
-
2. **Idea to Code**: PM
|
|
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
|
|
148
|
-
5. **Bug Fix**: Dev
|
|
149
|
-
6. **Documentation**: Analyst
|
|
150
|
-
7. **Quality Complete**: Tea
|
|
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
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('\
|
|
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('\
|
|
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 '
|
|
220
|
-
case 'medium': return '
|
|
221
|
-
case 'complex': return '
|
|
222
|
-
default: return '
|
|
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
|
|
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
|
|
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
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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'
|
|
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., '
|
|
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 -
|
|
3
|
-
*
|
|
4
|
-
*
|
|
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
|
-
//
|
|
66
|
+
// Raw modules exposed for the CLI, the web UI, and tests
|
|
172
67
|
detector,
|
|
173
68
|
platformSelector,
|
|
174
69
|
updater,
|