create-byan-agent 1.2.4 → 1.2.6

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 CHANGED
@@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.2.4] - 2026-02-04
8
+ ## [1.2.6] - 2026-02-04
9
9
 
10
10
  ### Added
11
11
  - **Interactive override**: `--interactive` flag to force prompts even without TTY (useful in npm scripts).
12
+ - **Agent-assisted interview**: Copilot CLI can answer installer questions automatically (fallback to classic prompts).
13
+ - **Provider fallback**: If Copilot CLI is unavailable, use Codex CLI, then Claude CLI when available.
14
+ - **Agent provider override**: `--agent-provider=codex|copilot|claude` to force the interview source.
12
15
 
13
16
  ### Changed
14
17
  - **Interview defaults**: Preselect detected or provided platforms during the interview.
package/README.md CHANGED
@@ -1025,6 +1025,17 @@ create-byan-agent --interactive
1025
1025
 
1026
1026
  # Custom mode with specific platform
1027
1027
  create-byan-agent --mode=custom --platforms=copilot-cli
1028
+
1029
+ # Install on all supported platforms
1030
+ create-byan-agent --platforms=all
1031
+
1032
+ # Disable agent-assisted interview (fallback to classic prompts)
1033
+ create-byan-agent --no-agent-interview
1034
+
1035
+ # Agent-assisted interview provider (auto selection)
1036
+ # Priority: Copilot CLI → Codex CLI → Claude CLI (if available)
1037
+ # Override provider explicitly (if installed):
1038
+ # create-byan-agent --agent-provider=codex
1028
1039
 
1029
1040
  # Full installation without backup
1030
1041
  create-byan-agent --mode=full --no-backup
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const path = require('path');
4
- const { program } = require('commander');
4
+ const { program } = require('commander');
5
+ const { spawnSync, execSync } = require('child_process');
6
+ const fs = require('fs');
7
+ const os = require('os');
5
8
  const chalk = require('chalk');
6
9
 
7
10
  // YANSTALLER Modules
@@ -14,7 +17,7 @@ const wizard = require('../lib/yanstaller/wizard');
14
17
  const backuper = require('../lib/yanstaller/backuper');
15
18
  const logger = require('../lib/utils/logger');
16
19
 
17
- const YANSTALLER_VERSION = '1.2.3';
20
+ const YANSTALLER_VERSION = '1.2.6';
18
21
 
19
22
  function parseList(value) {
20
23
  if (!value) return [];
@@ -36,6 +39,246 @@ function normalizePlatforms(list) {
36
39
  return list.map(normalizePlatformName).filter(Boolean);
37
40
  }
38
41
 
42
+ function expandAllPlatforms(list) {
43
+ if (list.includes('all')) {
44
+ return ['copilot-cli', 'vscode', 'codex', 'claude-code'];
45
+ }
46
+ return list;
47
+ }
48
+
49
+ function getCopilotCommand() {
50
+ try {
51
+ execSync('copilot --version', { stdio: 'ignore' });
52
+ return 'copilot';
53
+ } catch {}
54
+
55
+ try {
56
+ const isWin = process.platform === 'win32';
57
+ const probe = isWin ? 'where copilot' : 'which copilot';
58
+ const out = execSync(probe, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
59
+ const first = String(out).split(/\r?\n/).find(Boolean);
60
+ return first || null;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+
66
+ function getCodexCommand() {
67
+ try {
68
+ execSync('codex --version', { stdio: 'ignore' });
69
+ return 'codex';
70
+ } catch {}
71
+
72
+ try {
73
+ const isWin = process.platform === 'win32';
74
+ const probe = isWin ? 'where codex' : 'which codex';
75
+ const out = execSync(probe, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
76
+ const first = String(out).split(/\r?\n/).find(Boolean);
77
+ return first || null;
78
+ } catch {
79
+ return null;
80
+ }
81
+ }
82
+
83
+ function getClaudeCommand() {
84
+ try {
85
+ execSync('claude --version', { stdio: 'ignore' });
86
+ return 'claude';
87
+ } catch {}
88
+
89
+ try {
90
+ const isWin = process.platform === 'win32';
91
+ const probe = isWin ? 'where claude' : 'which claude';
92
+ const out = execSync(probe, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
93
+ const first = String(out).split(/\r?\n/).find(Boolean);
94
+ return first || null;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+
100
+ function stripAnsi(input) {
101
+ return input.replace(/\u001b\[[0-9;]*m/g, '');
102
+ }
103
+
104
+ function extractJson(text) {
105
+ const cleaned = stripAnsi(text).trim();
106
+ try {
107
+ return JSON.parse(cleaned);
108
+ } catch {
109
+ const xmlMatch = cleaned.match(/<json>[\s\S]*?<\/json>/i);
110
+ if (xmlMatch) {
111
+ const inner = xmlMatch[0].replace(/<\/?json>/gi, '').trim();
112
+ try {
113
+ return JSON.parse(inner);
114
+ } catch {
115
+ return null;
116
+ }
117
+ }
118
+ const match = cleaned.match(/\{[\s\S]*\}/);
119
+ if (!match) return null;
120
+ try {
121
+ return JSON.parse(match[0]);
122
+ } catch {
123
+ return null;
124
+ }
125
+ }
126
+ }
127
+
128
+ function runCopilotInterview({ recommendation, detection, projectRoot }) {
129
+ const copilotCmd = getCopilotCommand();
130
+ if (!copilotCmd) {
131
+ return { error: 'Copilot CLI not found in PATH' };
132
+ }
133
+ const platforms = (detection && Array.isArray(detection.platforms)) ? detection.platforms : [];
134
+ const detectedNames = platforms.filter(p => p.detected).map(p => p.name);
135
+ const recommendedAgents = (recommendation && recommendation.agents) ? recommendation.agents : [];
136
+ const recommendedMode = (recommendation && recommendation.mode) ? recommendation.mode : 'recommended';
137
+
138
+ const prompt = [
139
+ 'You are BYAN installer assistant.',
140
+ 'Based on the project context, provide installation preferences as STRICT JSON only.',
141
+ 'Do not include any extra text, markdown, or code fences.',
142
+ 'If you must include extra text, wrap JSON between <json> and </json>.',
143
+ '',
144
+ `Project root: ${projectRoot}`,
145
+ `Detected platforms: ${detectedNames.join(', ') || 'none'}`,
146
+ `Recommended agents: ${recommendedAgents.join(', ') || 'none'}`,
147
+ `Recommended mode: ${recommendedMode}`,
148
+ '',
149
+ 'Return JSON with keys:',
150
+ 'userName (string), language (English|Francais), mode (recommended|minimal|full|custom),',
151
+ 'agents (array of strings; required if mode=custom),',
152
+ 'platforms (array from: copilot-cli,vscode,codex,claude-code),',
153
+ 'createSampleAgent (boolean), createBackup (boolean).',
154
+ '',
155
+ 'If unsure, choose recommended mode, recommended agents, and detected platforms.',
156
+ 'JSON only.'
157
+ ].join('\n');
158
+
159
+ const spawnOptions = { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 };
160
+ let result;
161
+
162
+ if (process.platform === 'win32') {
163
+ const tmpFile = path.join(os.tmpdir(), `byan-copilot-prompt-${Date.now()}.txt`);
164
+ fs.writeFileSync(tmpFile, prompt, 'utf8');
165
+ const psFile = path.join(os.tmpdir(), `byan-copilot-run-${Date.now()}.ps1`);
166
+ const psContent = [
167
+ `$p = Get-Content -Raw '${tmpFile}'`,
168
+ 'copilot -p $p'
169
+ ].join('\n');
170
+ fs.writeFileSync(psFile, psContent, 'utf8');
171
+ result = spawnSync('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', psFile], spawnOptions);
172
+ try { fs.unlinkSync(tmpFile); } catch {}
173
+ try { fs.unlinkSync(psFile); } catch {}
174
+ } else {
175
+ result = spawnSync(copilotCmd, ['-p', prompt], spawnOptions);
176
+ }
177
+ if (result.error) {
178
+ return { error: result.error.message };
179
+ }
180
+ if (result.status !== 0) {
181
+ return { error: result.stderr || 'copilot returned non-zero status' };
182
+ }
183
+ const parsed = extractJson(result.stdout || '');
184
+ if (!parsed) {
185
+ return { error: 'Failed to parse JSON from copilot output' };
186
+ }
187
+ return { data: parsed };
188
+ }
189
+
190
+ function runCodexInterview({ recommendation, detection, projectRoot }) {
191
+ const codexCmd = getCodexCommand();
192
+ if (!codexCmd) {
193
+ return { error: 'Codex CLI not found in PATH' };
194
+ }
195
+ const platforms = (detection && Array.isArray(detection.platforms)) ? detection.platforms : [];
196
+ const detectedNames = platforms.filter(p => p.detected).map(p => p.name);
197
+ const recommendedAgents = (recommendation && recommendation.agents) ? recommendation.agents : [];
198
+ const recommendedMode = (recommendation && recommendation.mode) ? recommendation.mode : 'recommended';
199
+
200
+ const prompt = [
201
+ 'You are BYAN installer assistant.',
202
+ 'Based on the project context, provide installation preferences as STRICT JSON only.',
203
+ 'Do not include any extra text, markdown, or code fences.',
204
+ 'If you must include extra text, wrap JSON between <json> and </json>.',
205
+ '',
206
+ `Project root: ${projectRoot}`,
207
+ `Detected platforms: ${detectedNames.join(', ') || 'none'}`,
208
+ `Recommended agents: ${recommendedAgents.join(', ') || 'none'}`,
209
+ `Recommended mode: ${recommendedMode}`,
210
+ '',
211
+ 'Return JSON with keys:',
212
+ 'userName (string), language (English|Francais), mode (recommended|minimal|full|custom),',
213
+ 'agents (array of strings; required if mode=custom),',
214
+ 'platforms (array from: copilot-cli,vscode,codex,claude-code),',
215
+ 'createSampleAgent (boolean), createBackup (boolean).',
216
+ '',
217
+ 'If unsure, choose recommended mode, recommended agents, and detected platforms.',
218
+ 'JSON only.'
219
+ ].join('\n');
220
+
221
+ const spawnOptions = { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024, shell: process.platform === 'win32' };
222
+ const result = spawnSync(codexCmd, ['exec', prompt], spawnOptions);
223
+ if (result.error) {
224
+ return { error: result.error.message };
225
+ }
226
+ if (result.status !== 0) {
227
+ return { error: result.stderr || 'codex returned non-zero status' };
228
+ }
229
+ const parsed = extractJson(result.stdout || '');
230
+ if (!parsed) {
231
+ return { error: 'Failed to parse JSON from codex output' };
232
+ }
233
+ return { data: parsed };
234
+ }
235
+
236
+ function runClaudeInterview({ recommendation, detection, projectRoot }) {
237
+ const claudeCmd = getClaudeCommand();
238
+ if (!claudeCmd) {
239
+ return { error: 'Claude CLI not found in PATH' };
240
+ }
241
+ const platforms = (detection && Array.isArray(detection.platforms)) ? detection.platforms : [];
242
+ const detectedNames = platforms.filter(p => p.detected).map(p => p.name);
243
+ const recommendedAgents = (recommendation && recommendation.agents) ? recommendation.agents : [];
244
+ const recommendedMode = (recommendation && recommendation.mode) ? recommendation.mode : 'recommended';
245
+
246
+ const prompt = [
247
+ 'You are BYAN installer assistant.',
248
+ 'Based on the project context, provide installation preferences as STRICT JSON only.',
249
+ 'Do not include any extra text, markdown, or code fences.',
250
+ 'If you must include extra text, wrap JSON between <json> and </json>.',
251
+ '',
252
+ `Project root: ${projectRoot}`,
253
+ `Detected platforms: ${detectedNames.join(', ') || 'none'}`,
254
+ `Recommended agents: ${recommendedAgents.join(', ') || 'none'}`,
255
+ `Recommended mode: ${recommendedMode}`,
256
+ '',
257
+ 'Return JSON with keys:',
258
+ 'userName (string), language (English|Francais), mode (recommended|minimal|full|custom),',
259
+ 'agents (array of strings; required if mode=custom),',
260
+ 'platforms (array from: copilot-cli,vscode,codex,claude-code),',
261
+ 'createSampleAgent (boolean), createBackup (boolean).',
262
+ '',
263
+ 'If unsure, choose recommended mode, recommended agents, and detected platforms.',
264
+ 'JSON only.'
265
+ ].join('\n');
266
+
267
+ const spawnOptions = { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 };
268
+ const result = spawnSync(claudeCmd, ['-p', prompt], spawnOptions);
269
+ if (result.error) {
270
+ return { error: result.error.message };
271
+ }
272
+ if (result.status !== 0) {
273
+ return { error: result.stderr || 'claude returned non-zero status' };
274
+ }
275
+ const parsed = extractJson(result.stdout || '');
276
+ if (!parsed) {
277
+ return { error: 'Failed to parse JSON from claude output' };
278
+ }
279
+ return { data: parsed };
280
+ }
281
+
39
282
  // ASCII Art Banner
40
283
  const banner = `
41
284
  ${chalk.blue('╔════════════════════════════════════════════════════════════╗')}
@@ -111,7 +354,7 @@ async function main(options = {}) {
111
354
  logger.info(chalk.bold('\nSTEP 3/7: Interview (skipped - silent)\n'));
112
355
 
113
356
  const parsedAgents = parseList(options.agents);
114
- const parsedPlatforms = normalizePlatforms(parseList(options.platforms));
357
+ const parsedPlatforms = expandAllPlatforms(normalizePlatforms(parseList(options.platforms)));
115
358
 
116
359
  let mode = options.mode || (parsedAgents.length > 0 ? 'custom' : (recommendations.mode || 'minimal'));
117
360
  let agents = parsedAgents;
@@ -148,11 +391,104 @@ async function main(options = {}) {
148
391
  createBackup: options.backup !== false
149
392
  };
150
393
  } else {
394
+ const wantsAgentInterview = options.agentInterview !== false;
395
+ const useAgentInterview = wantsAgentInterview;
396
+
397
+ let agentDefaults = null;
398
+
399
+ if (useAgentInterview) {
400
+ let provider = null;
401
+ const requestedProvider = options.agentProvider ? String(options.agentProvider).toLowerCase() : 'auto';
402
+ const hasCopilot = !!getCopilotCommand();
403
+ const hasCodex = !!getCodexCommand();
404
+ const hasClaude = !!getClaudeCommand();
405
+
406
+ if (requestedProvider !== 'auto') {
407
+ if (requestedProvider === 'copilot' && hasCopilot) provider = 'copilot';
408
+ if (requestedProvider === 'codex' && hasCodex) provider = 'codex';
409
+ if (requestedProvider === 'claude' && hasClaude) provider = 'claude';
410
+
411
+ if (!provider) {
412
+ logger.info(`Requested agent provider "${requestedProvider}" is not available. Falling back to auto selection.`);
413
+ }
414
+ }
415
+
416
+ if (!provider) {
417
+ if (hasCopilot) {
418
+ provider = 'copilot';
419
+ } else if (hasCodex) {
420
+ provider = 'codex';
421
+ } else if (hasClaude) {
422
+ provider = 'claude';
423
+ }
424
+ }
425
+
426
+ if (provider) {
427
+ const label = provider === 'copilot' ? 'Copilot CLI' : provider === 'codex' ? 'Codex CLI' : 'Claude CLI';
428
+ logger.info(chalk.bold('\nSTEP 3/7: Interview (agent-assisted)\n'));
429
+ logger.info(`Launching agent-assisted interview via ${label}...`);
430
+
431
+ const agentResult = provider === 'copilot'
432
+ ? runCopilotInterview({ recommendation: recommendations, detection, projectRoot })
433
+ : provider === 'codex'
434
+ ? runCodexInterview({ recommendation: recommendations, detection, projectRoot })
435
+ : runClaudeInterview({ recommendation: recommendations, detection, projectRoot });
436
+
437
+ if (agentResult && agentResult.data) {
438
+ logger.info(`${label} returned JSON defaults.`);
439
+ const data = agentResult.data;
440
+ const agentMode = data.mode || 'recommended';
441
+
442
+ let agentPlatforms = Array.isArray(data.platforms) ? data.platforms : [];
443
+ agentPlatforms = expandAllPlatforms(normalizePlatforms(agentPlatforms));
444
+ if (agentPlatforms.length === 0) {
445
+ agentPlatforms = (detection.platforms || [])
446
+ .filter(p => p.detected)
447
+ .map(p => normalizePlatformName(p.name));
448
+ }
449
+
450
+ let agentAgents = Array.isArray(data.agents) ? data.agents : [];
451
+ if (agentAgents.length === 0) {
452
+ if (agentMode === 'recommended' && recommendations && recommendations.agents) {
453
+ agentAgents = recommendations.agents;
454
+ } else if (agentMode === 'minimal' || agentMode === 'full') {
455
+ agentAgents = recommender.getAgentList(agentMode);
456
+ } else if (agentMode === 'custom') {
457
+ agentAgents = recommendations.agents || ['byan'];
458
+ } else {
459
+ agentAgents = recommendations.agents || ['byan'];
460
+ }
461
+ }
462
+
463
+ const language = data.language === 'Francais' ? 'Francais' : 'English';
464
+
465
+ agentDefaults = {
466
+ userName: data.userName || 'Developer',
467
+ language,
468
+ mode: agentMode,
469
+ agents: agentAgents,
470
+ platforms: agentPlatforms,
471
+ createSampleAgent: !!data.createSampleAgent,
472
+ createBackup: data.createBackup !== false
473
+ };
474
+
475
+ logger.info('Agent provided recommended defaults. You can edit them below.');
476
+ } else {
477
+ const errMsg = agentResult && agentResult.error ? agentResult.error : 'unknown error';
478
+ logger.info(`Agent interview unavailable: ${errMsg}`);
479
+ logger.info('Continuing with standard interactive interview.');
480
+ }
481
+ } else {
482
+ logger.info('No agent CLI detected (Copilot/Codex/Claude). Continuing with standard interactive interview.');
483
+ }
484
+ }
485
+
151
486
  logger.info(chalk.bold('\nSTEP 3/7: Interview\n'));
152
- const preferredPlatforms = normalizePlatforms(parseList(options.platforms));
487
+ const preferredPlatforms = expandAllPlatforms(normalizePlatforms(parseList(options.platforms)));
153
488
  answers = await interviewer.ask(recommendations, {
154
489
  detection,
155
- preferredPlatforms
490
+ preferredPlatforms: agentDefaults ? agentDefaults.platforms : preferredPlatforms,
491
+ defaults: agentDefaults || undefined
156
492
  });
157
493
 
158
494
  if (options.backup === false) {
@@ -238,7 +574,9 @@ program
238
574
  .version(YANSTALLER_VERSION)
239
575
  .option('--silent', 'Silent installation (no prompts)')
240
576
  .option('--interactive', 'Force interactive prompts even without TTY')
241
- .option('--agents <agents>', 'Comma-separated list of agents to install')
577
+ .option('--no-agent-interview', 'Disable agent-assisted interview (Copilot CLI)')
578
+ .option('--agent-provider <provider>', 'Agent interview provider: auto|copilot|codex|claude')
579
+ .option('--agents <agents>', 'Comma-separated list of agents to install')
242
580
  .option('--platforms <platforms>', 'Comma-separated list of platforms (copilot-cli,vscode,claude-code,codex)')
243
581
  .option('--mode <mode>', 'Installation mode: recommended, custom, minimal, full')
244
582
  .option('--no-backup', 'Skip pre-install backup')
@@ -53,6 +53,7 @@ function buildDefaultPlatforms(options = {}) {
53
53
  * @returns {Promise<InterviewResult>}
54
54
  */
55
55
  async function ask(recommendation, options = {}) {
56
+ const defaults = options.defaults || {};
56
57
  logger.info(chalk.bold('\n🎙️ YANSTALLER Quick Interview\n'));
57
58
  logger.info('Just 5-7 questions to personalize your BYAN installation (<5 min)\n');
58
59
 
@@ -62,7 +63,7 @@ async function ask(recommendation, options = {}) {
62
63
  type: 'input',
63
64
  name: 'userName',
64
65
  message: 'What\'s your name?',
65
- default: 'Developer',
66
+ default: defaults.userName || 'Developer',
66
67
  validate: (input) => input.trim().length > 0 || 'Name cannot be empty'
67
68
  }
68
69
  ]);
@@ -77,12 +78,13 @@ async function ask(recommendation, options = {}) {
77
78
  { name: 'English', value: 'English' },
78
79
  { name: 'Français', value: 'Francais' }
79
80
  ],
80
- default: 'English'
81
+ default: (defaults.language === 'Francais' || defaults.language === 'English') ? defaults.language : 'English'
81
82
  }
82
83
  ]);
83
84
 
84
85
  // Q3: Installation mode (with recommendation)
85
- const recommendedMode = recommendation ? recommendation.mode : 'recommended';
86
+ const recommendedMode = recommendation ? recommendation.mode : 'recommended';
87
+ const defaultMode = defaults.mode || recommendedMode;
86
88
  const modeChoices = [
87
89
  {
88
90
  name: `Recommended - Based on your project (${recommendation ? recommendation.agents.length : 7} agents)`,
@@ -112,7 +114,7 @@ async function ask(recommendation, options = {}) {
112
114
  name: 'mode',
113
115
  message: 'Installation mode?',
114
116
  choices: modeChoices,
115
- default: recommendedMode
117
+ default: defaultMode
116
118
  }
117
119
  ]);
118
120
 
@@ -124,7 +126,7 @@ async function ask(recommendation, options = {}) {
124
126
  type: 'checkbox',
125
127
  name: 'agents',
126
128
  message: 'Select agents to install:',
127
- choices: getAgentChoices(),
129
+ choices: getAgentChoices(defaults.agents),
128
130
  pageSize: 15,
129
131
  validate: (input) => input.length > 0 || 'Select at least one agent'
130
132
  }
@@ -149,6 +151,7 @@ async function ask(recommendation, options = {}) {
149
151
  name: 'platforms',
150
152
  message: 'Which platforms to install on?',
151
153
  choices: [
154
+ { name: 'All detected platforms', value: '__all_detected__', checked: false },
152
155
  { name: 'GitHub Copilot CLI (.github/agents/)', value: 'copilot-cli', checked: isDefault('copilot-cli', true) },
153
156
  { name: 'VSCode Copilot Extension', value: 'vscode', checked: isDefault('vscode', true) },
154
157
  { name: 'Codex (.codex/prompts/)', value: 'codex', checked: isDefault('codex', false) },
@@ -157,6 +160,22 @@ async function ask(recommendation, options = {}) {
157
160
  validate: (input) => input.length > 0 || 'Select at least one platform'
158
161
  }
159
162
  ]);
163
+
164
+ let selectedPlatforms = platformAnswer.platforms;
165
+ if (selectedPlatforms.includes('__all_detected__')) {
166
+ const detected = buildDefaultPlatforms(options);
167
+ selectedPlatforms = detected.length > 0
168
+ ? detected
169
+ : ['copilot-cli', 'vscode', 'codex', 'claude-code'];
170
+ }
171
+
172
+ const isFrench = langAnswer.language === 'Francais';
173
+ const platformSummary = selectedPlatforms.join(', ');
174
+ if (isFrench) {
175
+ logger.info(`Plateformes retenues: ${platformSummary}`);
176
+ } else {
177
+ logger.info(`Selected platforms: ${platformSummary}`);
178
+ }
160
179
 
161
180
  // Q6: Create sample agent
162
181
  const sampleAnswer = await inquirer.prompt([
@@ -164,7 +183,7 @@ async function ask(recommendation, options = {}) {
164
183
  type: 'confirm',
165
184
  name: 'createSample',
166
185
  message: 'Launch BYAN agent creator after installation?',
167
- default: false
186
+ default: typeof defaults.createSampleAgent === 'boolean' ? defaults.createSampleAgent : false
168
187
  }
169
188
  ]);
170
189
 
@@ -174,22 +193,22 @@ async function ask(recommendation, options = {}) {
174
193
  type: 'confirm',
175
194
  name: 'createBackup',
176
195
  message: 'Create backup of existing _bmad/ directory? (if exists)',
177
- default: true
196
+ default: typeof defaults.createBackup === 'boolean' ? defaults.createBackup : true
178
197
  }
179
198
  ]);
180
199
 
181
200
  logger.info('');
182
201
 
183
- return {
184
- userName: nameAnswer.userName,
185
- language: langAnswer.language,
186
- mode: modeAnswer.mode,
187
- agents: selectedAgents,
188
- targetPlatforms: platformAnswer.platforms,
189
- createSampleAgent: sampleAnswer.createSample,
190
- createBackup: backupAnswer.createBackup
191
- };
192
- }
202
+ return {
203
+ userName: nameAnswer.userName,
204
+ language: langAnswer.language,
205
+ mode: modeAnswer.mode,
206
+ agents: selectedAgents,
207
+ targetPlatforms: selectedPlatforms,
208
+ createSampleAgent: sampleAnswer.createSample,
209
+ createBackup: backupAnswer.createBackup
210
+ };
211
+ }
193
212
 
194
213
  /**
195
214
  * Ask single question
@@ -218,54 +237,58 @@ async function askQuestion(question, type, choices = []) {
218
237
  *
219
238
  * @returns {Array<{name: string, value: string, checked: boolean}>}
220
239
  */
221
- function getAgentChoices() {
222
- return [
223
- // BMB Module - Builders
224
- { name: '🏗️ BYAN - Agent Creator & Intelligent Interview', value: 'byan', checked: true },
225
- { name: '📦 RACHID - NPM/NPX Deployment Specialist', value: 'rachid', checked: true },
226
- { name: '🔧 Agent Builder - Direct agent creation', value: 'agent-builder', checked: false },
227
- { name: '📋 Module Builder - Module scaffolding', value: 'module-builder', checked: false },
228
- { name: '🔄 Workflow Builder - Workflow creation', value: 'workflow-builder', checked: false },
229
-
230
- // BMM Module - Development Team
231
- { name: '🔍 MARY (Analyst) - Requirements & Domain Expert', value: 'analyst', checked: false },
232
- { name: '📊 JOHN (PM) - Product Management', value: 'pm', checked: false },
233
- { name: '🏛️ WINSTON (Architect) - System Architecture', value: 'architect', checked: false },
234
- { name: '💻 AMELIA (Dev) - Implementation Specialist', value: 'dev', checked: true },
235
- { name: '📋 BOB (SM) - Scrum Master', value: 'sm', checked: false },
236
- { name: '🧪 QUINN (QA) - Quality Assurance', value: 'quinn', checked: false },
237
- { name: '🎨 SALLY (UX) - UX/UI Design', value: 'ux-designer', checked: false },
238
- { name: '📝 PAIGE (Tech Writer) - Documentation', value: 'tech-writer', checked: true },
239
-
240
- // TEA Module - Testing
241
- { name: '🧬 MURAT (TEA) - Test Architecture Expert', value: 'tea', checked: false },
242
-
243
- // CIS Module - Innovation
244
- { name: '💡 CARSON - Brainstorming Coach', value: 'brainstorming-coach', checked: false },
245
- { name: '🎯 DR. QUINN - Design Thinking Coach', value: 'design-thinking-coach', checked: false },
246
- { name: '🧩 MAYA - Creative Problem Solver', value: 'creative-problem-solver', checked: false },
247
- { name: '🚀 VICTOR - Innovation Strategist', value: 'innovation-strategist', checked: false },
248
- { name: '📽️ Presentation Master', value: 'presentation-master', checked: false },
249
- { name: '📖 Storyteller', value: 'storyteller', checked: false },
250
-
251
- // Core Module
252
- { name: '🎭 Party Mode - Multi-agent orchestration', value: 'party-mode', checked: false },
253
- { name: '🧠 BMAD Master - Platform orchestrator', value: 'bmad-master', checked: false },
254
-
255
- // Specialized
256
- { name: '🔌 MARC - GitHub Copilot CLI Integration', value: 'marc', checked: false },
257
- { name: '📌 PATNOTE - Update Manager', value: 'patnote', checked: false },
258
-
259
- // Quick Flow Variants
260
- { name: 'Quick Flow Solo Dev', value: 'quick-flow-solo-dev', checked: false }
261
- ];
262
- }
263
-
264
- /**
265
- * Get all agent names
266
- *
267
- * @returns {string[]}
268
- */
240
+ function getAgentChoices(checkedAgents = []) {
241
+ const choices = [
242
+ // BMB Module - Builders
243
+ { name: 'BYAN - Agent Creator & Intelligent Interview', value: 'byan', checked: true },
244
+ { name: 'RACHID - NPM/NPX Deployment Specialist', value: 'rachid', checked: true },
245
+ { name: 'Agent Builder - Direct agent creation', value: 'agent-builder', checked: false },
246
+ { name: 'Module Builder - Module scaffolding', value: 'module-builder', checked: false },
247
+ { name: 'Workflow Builder - Workflow creation', value: 'workflow-builder', checked: false },
248
+
249
+ // BMM Module - Development Team
250
+ { name: 'MARY (Analyst) - Requirements & Domain Expert', value: 'analyst', checked: false },
251
+ { name: 'JOHN (PM) - Product Management', value: 'pm', checked: false },
252
+ { name: 'WINSTON (Architect) - System Architecture', value: 'architect', checked: false },
253
+ { name: 'AMELIA (Dev) - Implementation Specialist', value: 'dev', checked: true },
254
+ { name: 'BOB (SM) - Scrum Master', value: 'sm', checked: false },
255
+ { name: 'QUINN (QA) - Quality Assurance', value: 'quinn', checked: false },
256
+ { name: 'SALLY (UX) - UX/UI Design', value: 'ux-designer', checked: false },
257
+ { name: 'PAIGE (Tech Writer) - Documentation', value: 'tech-writer', checked: true },
258
+
259
+ // TEA Module - Testing
260
+ { name: 'MURAT (TEA) - Test Architecture Expert', value: 'tea', checked: false },
261
+
262
+ // CIS Module - Innovation
263
+ { name: 'CARSON - Brainstorming Coach', value: 'brainstorming-coach', checked: false },
264
+ { name: 'DR. QUINN - Design Thinking Coach', value: 'design-thinking-coach', checked: false },
265
+ { name: 'MAYA - Creative Problem Solver', value: 'creative-problem-solver', checked: false },
266
+ { name: 'VICTOR - Innovation Strategist', value: 'innovation-strategist', checked: false },
267
+ { name: 'Presentation Master', value: 'presentation-master', checked: false },
268
+ { name: 'Storyteller', value: 'storyteller', checked: false },
269
+
270
+ // Core Module
271
+ { name: 'Party Mode - Multi-agent orchestration', value: 'party-mode', checked: false },
272
+ { name: 'BMAD Master - Platform orchestrator', value: 'bmad-master', checked: false },
273
+
274
+ // Specialized
275
+ { name: 'MARC - GitHub Copilot CLI Integration', value: 'marc', checked: false },
276
+ { name: 'PATNOTE - Update Manager', value: 'patnote', checked: false },
277
+
278
+ // Quick Flow Variants
279
+ { name: 'Quick Flow Solo Dev', value: 'quick-flow-solo-dev', checked: false }
280
+ ];
281
+
282
+ if (Array.isArray(checkedAgents) && checkedAgents.length > 0) {
283
+ return choices.map(choice => ({
284
+ ...choice,
285
+ checked: checkedAgents.includes(choice.value)
286
+ }));
287
+ }
288
+
289
+ return choices;
290
+ }
291
+
269
292
  function getAllAgents() {
270
293
  return getAgentChoices().map(choice => choice.value);
271
294
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-byan-agent",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "NPX installer for BYAN ecosystem - Agent creators (BYAN, BYAN-Test) with deployment (RACHID), integration (MARC), updates (PATNOTE), and optimization (CARMACK)",
5
5
  "bin": {
6
6
  "create-byan-agent": "bin/create-byan-agent.js"