create-byan-agent 1.2.3 → 1.2.4
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 +15 -1
- package/README.md +10 -7
- package/bin/create-byan-agent.js +112 -23
- package/lib/utils/file-utils.js +19 -17
- package/lib/yanstaller/installer.js +11 -10
- package/lib/yanstaller/interviewer.js +48 -20
- package/lib/yanstaller/validator.js +48 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,21 @@ 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.
|
|
8
|
+
## [1.2.4] - 2026-02-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Interactive override**: `--interactive` flag to force prompts even without TTY (useful in npm scripts).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- **Interview defaults**: Preselect detected or provided platforms during the interview.
|
|
15
|
+
- **E2E**: Run with explicit platforms to validate stub generation.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- **Silent mode**: Skip interview and wizard with safe defaults to prevent hangs in non-interactive runs.
|
|
19
|
+
- **Platform normalization**: Map `claude` to `claude-code` for installer/platform parity.
|
|
20
|
+
- **Validator**: Use YAML parser correctly and remove false warnings (permissions/templates).
|
|
21
|
+
|
|
22
|
+
## [1.2.3] - 2026-02-03
|
|
9
23
|
|
|
10
24
|
### Added
|
|
11
25
|
- **E2E Test Suite** - Automated end-to-end testing before npm publish
|
package/README.md
CHANGED
|
@@ -1015,13 +1015,16 @@ const validation = await yanstaller.validate({
|
|
|
1015
1015
|
console.log(validation.errors); // []
|
|
1016
1016
|
```
|
|
1017
1017
|
|
|
1018
|
-
#### CLI Options
|
|
1019
|
-
```bash
|
|
1020
|
-
# Silent installation with specific agents
|
|
1021
|
-
create-byan-agent --silent --agents=byan,dev,quinn
|
|
1022
|
-
|
|
1023
|
-
#
|
|
1024
|
-
create-byan-agent --
|
|
1018
|
+
#### CLI Options
|
|
1019
|
+
```bash
|
|
1020
|
+
# Silent installation with specific agents
|
|
1021
|
+
create-byan-agent --silent --agents=byan,dev,quinn
|
|
1022
|
+
|
|
1023
|
+
# Force interactive prompts (useful inside npm scripts or CI shells without TTY)
|
|
1024
|
+
create-byan-agent --interactive
|
|
1025
|
+
|
|
1026
|
+
# Custom mode with specific platform
|
|
1027
|
+
create-byan-agent --mode=custom --platforms=copilot-cli
|
|
1025
1028
|
|
|
1026
1029
|
# Full installation without backup
|
|
1027
1030
|
create-byan-agent --mode=full --no-backup
|
package/bin/create-byan-agent.js
CHANGED
|
@@ -14,9 +14,29 @@ const wizard = require('../lib/yanstaller/wizard');
|
|
|
14
14
|
const backuper = require('../lib/yanstaller/backuper');
|
|
15
15
|
const logger = require('../lib/utils/logger');
|
|
16
16
|
|
|
17
|
-
const YANSTALLER_VERSION = '1.2.3';
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const YANSTALLER_VERSION = '1.2.3';
|
|
18
|
+
|
|
19
|
+
function parseList(value) {
|
|
20
|
+
if (!value) return [];
|
|
21
|
+
if (Array.isArray(value)) return value.map(v => String(v).trim()).filter(Boolean);
|
|
22
|
+
return String(value)
|
|
23
|
+
.split(',')
|
|
24
|
+
.map(v => v.trim())
|
|
25
|
+
.filter(Boolean);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function normalizePlatformName(name) {
|
|
29
|
+
if (!name) return name;
|
|
30
|
+
const lower = String(name).toLowerCase();
|
|
31
|
+
if (lower === 'claude') return 'claude-code';
|
|
32
|
+
return lower;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizePlatforms(list) {
|
|
36
|
+
return list.map(normalizePlatformName).filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ASCII Art Banner
|
|
20
40
|
const banner = `
|
|
21
41
|
${chalk.blue('╔════════════════════════════════════════════════════════════╗')}
|
|
22
42
|
${chalk.blue('║')} ${chalk.blue('║')}
|
|
@@ -41,7 +61,7 @@ ${chalk.blue('╚═════════════════════
|
|
|
41
61
|
* 6. VALIDATE - 10 automated checks
|
|
42
62
|
* 7. WIZARD - Post-install actions
|
|
43
63
|
*/
|
|
44
|
-
async function main() {
|
|
64
|
+
async function main(options = {}) {
|
|
45
65
|
try {
|
|
46
66
|
console.clear();
|
|
47
67
|
console.log(banner);
|
|
@@ -72,11 +92,75 @@ async function main() {
|
|
|
72
92
|
logger.info(`✓ Recommended agents: ${chalk.cyan(recommendations.agents.join(', '))}`);
|
|
73
93
|
}
|
|
74
94
|
|
|
75
|
-
// STEP 3: INTERVIEW - 7-Question Personalization
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
95
|
+
// STEP 3: INTERVIEW - 7-Question Personalization
|
|
96
|
+
const isSilent = !!options.silent;
|
|
97
|
+
const forceInteractive = !!options.interactive;
|
|
98
|
+
const hasTty = !!process.stdin.isTTY;
|
|
99
|
+
const forceSilent = !hasTty && !isSilent && !forceInteractive;
|
|
100
|
+
|
|
101
|
+
if (forceSilent) {
|
|
102
|
+
logger.warn('No interactive TTY detected. Falling back to silent mode.');
|
|
103
|
+
}
|
|
104
|
+
if (!hasTty && forceInteractive) {
|
|
105
|
+
logger.warn('Interactive mode forced without TTY. Prompts may not render correctly.');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let answers;
|
|
109
|
+
|
|
110
|
+
if (isSilent || forceSilent) {
|
|
111
|
+
logger.info(chalk.bold('\nSTEP 3/7: Interview (skipped - silent)\n'));
|
|
112
|
+
|
|
113
|
+
const parsedAgents = parseList(options.agents);
|
|
114
|
+
const parsedPlatforms = normalizePlatforms(parseList(options.platforms));
|
|
115
|
+
|
|
116
|
+
let mode = options.mode || (parsedAgents.length > 0 ? 'custom' : (recommendations.mode || 'minimal'));
|
|
117
|
+
let agents = parsedAgents;
|
|
118
|
+
|
|
119
|
+
if (agents.length === 0) {
|
|
120
|
+
if (mode === 'recommended' && recommendations && recommendations.agents) {
|
|
121
|
+
agents = recommendations.agents;
|
|
122
|
+
} else if (mode === 'minimal' || mode === 'full') {
|
|
123
|
+
agents = recommender.getAgentList(mode);
|
|
124
|
+
} else if (mode === 'custom') {
|
|
125
|
+
logger.warn('Custom mode selected without agents. Falling back to recommendations.');
|
|
126
|
+
agents = recommendations.agents || ['byan'];
|
|
127
|
+
mode = 'recommended';
|
|
128
|
+
} else {
|
|
129
|
+
agents = recommendations.agents || ['byan'];
|
|
130
|
+
mode = recommendations.mode || 'minimal';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let targetPlatforms = parsedPlatforms;
|
|
135
|
+
if (targetPlatforms.length === 0) {
|
|
136
|
+
targetPlatforms = (detection.platforms || [])
|
|
137
|
+
.filter(p => p.detected)
|
|
138
|
+
.map(p => normalizePlatformName(p.name));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
answers = {
|
|
142
|
+
userName: 'Developer',
|
|
143
|
+
language: 'English',
|
|
144
|
+
mode,
|
|
145
|
+
agents,
|
|
146
|
+
targetPlatforms,
|
|
147
|
+
createSampleAgent: false,
|
|
148
|
+
createBackup: options.backup !== false
|
|
149
|
+
};
|
|
150
|
+
} else {
|
|
151
|
+
logger.info(chalk.bold('\nSTEP 3/7: Interview\n'));
|
|
152
|
+
const preferredPlatforms = normalizePlatforms(parseList(options.platforms));
|
|
153
|
+
answers = await interviewer.ask(recommendations, {
|
|
154
|
+
detection,
|
|
155
|
+
preferredPlatforms
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if (options.backup === false) {
|
|
159
|
+
answers.createBackup = false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// STEP 4: BACKUP (optional)
|
|
80
164
|
if (answers.createBackup) {
|
|
81
165
|
logger.info(chalk.bold('\n💾 STEP 4/7: Backup\n'));
|
|
82
166
|
try {
|
|
@@ -122,18 +206,22 @@ async function main() {
|
|
|
122
206
|
}
|
|
123
207
|
}
|
|
124
208
|
|
|
125
|
-
// STEP 7: WIZARD - Post-Install Actions
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
209
|
+
// STEP 7: WIZARD - Post-Install Actions
|
|
210
|
+
if (isSilent || forceSilent) {
|
|
211
|
+
logger.info(chalk.bold('\nSTEP 7/7: Post-Install Wizard (skipped - silent)\n'));
|
|
212
|
+
} else {
|
|
213
|
+
logger.info(chalk.bold('\nSTEP 7/7: Post-Install Wizard\n'));
|
|
214
|
+
await wizard.show({
|
|
215
|
+
agents: answers.agents,
|
|
216
|
+
targetPlatforms: answers.targetPlatforms,
|
|
217
|
+
mode: answers.mode,
|
|
218
|
+
projectRoot,
|
|
219
|
+
userName: answers.userName,
|
|
220
|
+
language: answers.language
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
} catch (error) {
|
|
137
225
|
logger.error(chalk.red('\n❌ Installation failed:\n'));
|
|
138
226
|
logger.error(error.message);
|
|
139
227
|
if (error.stack) {
|
|
@@ -148,13 +236,14 @@ program
|
|
|
148
236
|
.name('create-byan-agent')
|
|
149
237
|
.description('YANSTALLER - Intelligent installer for BYAN ecosystem (29 agents, multi-platform)')
|
|
150
238
|
.version(YANSTALLER_VERSION)
|
|
151
|
-
.option('--silent', 'Silent installation (no prompts)')
|
|
239
|
+
.option('--silent', 'Silent installation (no prompts)')
|
|
240
|
+
.option('--interactive', 'Force interactive prompts even without TTY')
|
|
152
241
|
.option('--agents <agents>', 'Comma-separated list of agents to install')
|
|
153
242
|
.option('--platforms <platforms>', 'Comma-separated list of platforms (copilot-cli,vscode,claude-code,codex)')
|
|
154
243
|
.option('--mode <mode>', 'Installation mode: recommended, custom, minimal, full')
|
|
155
244
|
.option('--no-backup', 'Skip pre-install backup')
|
|
156
245
|
.option('--dry-run', 'Simulate installation without making changes')
|
|
157
246
|
.option('--verbose', 'Verbose logging')
|
|
158
|
-
.action(main);
|
|
247
|
+
.action((opts) => main(opts));
|
|
159
248
|
|
|
160
249
|
program.parse(process.argv);
|
package/lib/utils/file-utils.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @module utils/file-utils
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const fs = require('fs-extra');
|
|
10
|
-
const path = require('path');
|
|
9
|
+
const fs = require('fs-extra');
|
|
10
|
+
const path = require('path');
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Copy file or directory
|
|
@@ -98,18 +98,20 @@ async function writeFile(filePath, content) {
|
|
|
98
98
|
* @param {string} dirPath - Directory path
|
|
99
99
|
* @returns {Promise<string[]>} - Array of file/directory names
|
|
100
100
|
*/
|
|
101
|
-
async function readDir(dirPath) {
|
|
102
|
-
return fs.readdir(dirPath);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
module.exports = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
async function readDir(dirPath) {
|
|
102
|
+
return fs.readdir(dirPath);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
constants: fs.constants,
|
|
107
|
+
copy,
|
|
108
|
+
exists,
|
|
109
|
+
ensureDir,
|
|
110
|
+
remove,
|
|
111
|
+
readJSON,
|
|
112
|
+
writeJSON,
|
|
113
|
+
readFile,
|
|
114
|
+
writeFile,
|
|
115
|
+
readDir,
|
|
116
|
+
access: fs.access
|
|
117
|
+
};
|
|
@@ -166,19 +166,20 @@ async function copyAgentFile(agentName, projectRoot) {
|
|
|
166
166
|
/**
|
|
167
167
|
* Generate platform stubs for all agents
|
|
168
168
|
*
|
|
169
|
-
* @param {string} platform - Platform name ('copilot-cli' | 'vscode' | 'claude' | 'codex')
|
|
169
|
+
* @param {string} platform - Platform name ('copilot-cli' | 'vscode' | 'claude-code' | 'codex')
|
|
170
170
|
* @param {InstallConfig} config - Installation config
|
|
171
171
|
* @returns {Promise<void>}
|
|
172
172
|
*/
|
|
173
|
-
async function generatePlatformStubs(platform, config) {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
async function generatePlatformStubs(platform, config) {
|
|
174
|
+
const normalized = platform === 'claude' ? 'claude-code' : platform;
|
|
175
|
+
const platformModule = require(`../platforms/${normalized}`);
|
|
176
|
+
|
|
177
|
+
if (!platformModule || typeof platformModule.install !== 'function') {
|
|
178
|
+
throw new Error(`Platform module not found or invalid: ${platform}`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
await platformModule.install(config.projectRoot, config.agents, config);
|
|
182
|
+
}
|
|
182
183
|
|
|
183
184
|
/**
|
|
184
185
|
* Create module config file
|
|
@@ -8,10 +8,34 @@
|
|
|
8
8
|
* @module yanstaller/interviewer
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const inquirer = require('inquirer');
|
|
12
|
-
const chalk = require('chalk');
|
|
13
|
-
const logger = require('../utils/logger');
|
|
14
|
-
|
|
11
|
+
const inquirer = require('inquirer');
|
|
12
|
+
const chalk = require('chalk');
|
|
13
|
+
const logger = require('../utils/logger');
|
|
14
|
+
|
|
15
|
+
function normalizePlatformName(name) {
|
|
16
|
+
if (!name) return name;
|
|
17
|
+
const lower = String(name).toLowerCase();
|
|
18
|
+
if (lower === 'claude') return 'claude-code';
|
|
19
|
+
return lower;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function buildDefaultPlatforms(options = {}) {
|
|
23
|
+
const preferred = Array.isArray(options.preferredPlatforms)
|
|
24
|
+
? options.preferredPlatforms.map(normalizePlatformName).filter(Boolean)
|
|
25
|
+
: [];
|
|
26
|
+
|
|
27
|
+
if (preferred.length > 0) return preferred;
|
|
28
|
+
|
|
29
|
+
const detected = (options.detection && Array.isArray(options.detection.platforms))
|
|
30
|
+
? options.detection.platforms
|
|
31
|
+
.filter(p => p.detected)
|
|
32
|
+
.map(p => normalizePlatformName(p.name))
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
: [];
|
|
35
|
+
|
|
36
|
+
return detected;
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
/**
|
|
16
40
|
* @typedef {Object} InterviewResult
|
|
17
41
|
* @property {string} userName
|
|
@@ -28,7 +52,7 @@ const logger = require('../utils/logger');
|
|
|
28
52
|
* @param {import('./recommender').Recommendation} recommendation - Recommended config
|
|
29
53
|
* @returns {Promise<InterviewResult>}
|
|
30
54
|
*/
|
|
31
|
-
async function ask(recommendation) {
|
|
55
|
+
async function ask(recommendation, options = {}) {
|
|
32
56
|
logger.info(chalk.bold('\n🎙️ YANSTALLER Quick Interview\n'));
|
|
33
57
|
logger.info('Just 5-7 questions to personalize your BYAN installation (<5 min)\n');
|
|
34
58
|
|
|
@@ -114,21 +138,25 @@ async function ask(recommendation) {
|
|
|
114
138
|
selectedAgents = getAllAgents();
|
|
115
139
|
}
|
|
116
140
|
|
|
117
|
-
// Q5: Target platforms
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
// Q5: Target platforms
|
|
142
|
+
const defaultPlatforms = buildDefaultPlatforms(options);
|
|
143
|
+
const useDefaultPlatforms = defaultPlatforms.length > 0;
|
|
144
|
+
const isDefault = (value, fallback) => useDefaultPlatforms ? defaultPlatforms.includes(value) : fallback;
|
|
145
|
+
|
|
146
|
+
const platformAnswer = await inquirer.prompt([
|
|
147
|
+
{
|
|
148
|
+
type: 'checkbox',
|
|
149
|
+
name: 'platforms',
|
|
150
|
+
message: 'Which platforms to install on?',
|
|
151
|
+
choices: [
|
|
152
|
+
{ name: 'GitHub Copilot CLI (.github/agents/)', value: 'copilot-cli', checked: isDefault('copilot-cli', true) },
|
|
153
|
+
{ name: 'VSCode Copilot Extension', value: 'vscode', checked: isDefault('vscode', true) },
|
|
154
|
+
{ name: 'Codex (.codex/prompts/)', value: 'codex', checked: isDefault('codex', false) },
|
|
155
|
+
{ name: 'Claude Code (MCP server)', value: 'claude-code', checked: isDefault('claude-code', false) }
|
|
156
|
+
],
|
|
157
|
+
validate: (input) => input.length > 0 || 'Select at least one platform'
|
|
158
|
+
}
|
|
159
|
+
]);
|
|
132
160
|
|
|
133
161
|
// Q6: Create sample agent
|
|
134
162
|
const sampleAnswer = await inquirer.prompt([
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const fileUtils = require('../utils/file-utils');
|
|
13
13
|
const yamlUtils = require('../utils/yaml-utils');
|
|
14
|
-
const { execSync } = require('child_process');
|
|
14
|
+
const { execSync } = require('child_process');
|
|
15
|
+
const fs = require('fs-extra');
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* @typedef {Object} ValidationResult
|
|
@@ -252,7 +253,7 @@ async function checkConfigFiles(config) {
|
|
|
252
253
|
if (await fileUtils.exists(configPath)) {
|
|
253
254
|
try {
|
|
254
255
|
const configContent = await fileUtils.readFile(configPath, 'utf8');
|
|
255
|
-
const parsedConfig = yamlUtils.
|
|
256
|
+
const parsedConfig = yamlUtils.parse(configContent);
|
|
256
257
|
|
|
257
258
|
// Validate required fields
|
|
258
259
|
if (!parsedConfig.user_name) {
|
|
@@ -484,28 +485,51 @@ async function checkWorkflows(config) {
|
|
|
484
485
|
/**
|
|
485
486
|
* Check 9: Templates valid
|
|
486
487
|
*/
|
|
487
|
-
async function checkTemplates(config) {
|
|
488
|
-
const templatesDir = path.join(__dirname, '..', '..', 'templates', '_bmad');
|
|
489
|
-
|
|
490
|
-
if (!await fileUtils.exists(templatesDir)) {
|
|
491
|
-
return {
|
|
492
|
-
id: 'templates',
|
|
493
|
-
name: 'Template files',
|
|
494
|
-
passed: false,
|
|
495
|
-
message: 'Templates directory not found',
|
|
496
|
-
severity: 'warning'
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
const
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
488
|
+
async function checkTemplates(config) {
|
|
489
|
+
const templatesDir = path.join(__dirname, '..', '..', 'templates', '_bmad');
|
|
490
|
+
|
|
491
|
+
if (!await fileUtils.exists(templatesDir)) {
|
|
492
|
+
return {
|
|
493
|
+
id: 'templates',
|
|
494
|
+
name: 'Template files',
|
|
495
|
+
passed: false,
|
|
496
|
+
message: 'Templates directory not found',
|
|
497
|
+
severity: 'warning'
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const entries = await fileUtils.readDir(templatesDir);
|
|
502
|
+
const modules = [];
|
|
503
|
+
for (const entry of entries) {
|
|
504
|
+
const entryPath = path.join(templatesDir, entry);
|
|
505
|
+
try {
|
|
506
|
+
const stat = await fs.stat(entryPath);
|
|
507
|
+
if (stat.isDirectory()) {
|
|
508
|
+
modules.push(entry);
|
|
509
|
+
}
|
|
510
|
+
} catch {
|
|
511
|
+
// Ignore unreadable entries
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (modules.length === 0) {
|
|
516
|
+
return {
|
|
517
|
+
id: 'templates',
|
|
518
|
+
name: 'Template files',
|
|
519
|
+
passed: false,
|
|
520
|
+
message: 'No template modules found',
|
|
521
|
+
severity: 'warning'
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const issues = [];
|
|
526
|
+
|
|
527
|
+
for (const module of modules) {
|
|
528
|
+
const agentsDir = path.join(templatesDir, module, 'agents');
|
|
529
|
+
if (!await fileUtils.exists(agentsDir)) {
|
|
530
|
+
issues.push(`${module}/agents missing`);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
509
533
|
|
|
510
534
|
if (issues.length > 0) {
|
|
511
535
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-byan-agent",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
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"
|