create-byan-agent 2.7.1 → 2.7.3

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.
@@ -15,7 +15,7 @@ const { getDomainQuestions, buildPhase2Prompt } = require('../lib/domain-questio
15
15
  const { generateProjectAgentsDoc } = require('../lib/project-agents-generator');
16
16
  const { launchPhase2Chat, generateDefaultConfig } = require('../lib/phase2-chat');
17
17
 
18
- const BYAN_VERSION = require('../../package.json').version;
18
+ const BYAN_VERSION = require('../package.json').version;
19
19
 
20
20
  // ASCII Art Banner
21
21
  const banner = `
@@ -1385,18 +1385,29 @@ async function install() {
1385
1385
 
1386
1386
  try {
1387
1387
  if (soulMode === 'creator') {
1388
- // Copy Yan's creator-soul as foundation + blank personal soul/tao
1388
+ // Copy Yan's soul files as active soul (creator mode = Yan's soul)
1389
1389
  const creatorSoulSrc = path.join(templateDir, '_byan', 'creator-soul.md');
1390
+ const byanSoulSrc = path.join(templateDir, '_byan', 'byan-soul.md');
1391
+ const byanTaoSrc = path.join(templateDir, '_byan', 'byan-tao.md');
1392
+ const byanMemorySrc = path.join(templateDir, '_byan', 'byan-soul-memory.md');
1390
1393
  const soulRefSrc = path.join(templateDir, '_byan', 'byan-soul-reference.md');
1391
1394
  const taoRefSrc = path.join(templateDir, '_byan', 'byan-tao-reference.md');
1392
1395
  const memoryRefSrc = path.join(templateDir, '_byan', 'soul-memory-reference.md');
1393
- const soulTemplateSrc = path.join(templateDir, '_byan', 'soul-template.md');
1394
- const memoryTemplateSrc = path.join(templateDir, '_byan', 'soul-memory-template.md');
1395
1396
 
1396
1397
  // Copy creator-soul as-is (Yan's soul = the original)
1397
1398
  if (await fs.pathExists(creatorSoulSrc)) {
1398
1399
  await fs.copy(creatorSoulSrc, path.join(soulDir, 'creator-soul.md'));
1399
1400
  }
1401
+ // Copy Yan's active soul files (what soul-activation.md actually reads)
1402
+ if (await fs.pathExists(byanSoulSrc)) {
1403
+ await fs.copy(byanSoulSrc, path.join(soulDir, 'soul.md'));
1404
+ }
1405
+ if (await fs.pathExists(byanTaoSrc)) {
1406
+ await fs.copy(byanTaoSrc, path.join(soulDir, 'tao.md'));
1407
+ }
1408
+ if (await fs.pathExists(byanMemorySrc)) {
1409
+ await fs.copy(byanMemorySrc, path.join(soulDir, 'soul-memory.md'));
1410
+ }
1400
1411
  // Copy references for inspiration
1401
1412
  if (await fs.pathExists(soulRefSrc)) {
1402
1413
  await fs.copy(soulRefSrc, path.join(soulDir, 'byan-soul-reference.md'));
@@ -1407,21 +1418,13 @@ async function install() {
1407
1418
  if (await fs.pathExists(memoryRefSrc)) {
1408
1419
  await fs.copy(memoryRefSrc, path.join(soulDir, 'soul-memory-reference.md'));
1409
1420
  }
1410
- // Create user's own soul from template (to be filled)
1411
- if (await fs.pathExists(soulTemplateSrc)) {
1412
- await fs.copy(soulTemplateSrc, path.join(soulDir, 'soul.md'));
1413
- }
1414
- if (await fs.pathExists(memoryTemplateSrc)) {
1415
- await fs.copy(memoryTemplateSrc, path.join(soulDir, 'soul-memory.md'));
1416
- }
1417
1421
 
1418
- soulSpinner.succeed('Soul system installed (Creator mode — Yan\'s soul as foundation)');
1419
- console.log(chalk.green(' + creator-soul.md — Yan\'s original soul (read-only reference)'));
1420
- console.log(chalk.green(' + byan-soul-reference.md — BYAN\'s soul (example)'));
1421
- console.log(chalk.green(' + byan-tao-reference.md — BYAN\'s voice (example)'));
1422
- console.log(chalk.green(' + soul.md — YOUR soul (fill with your values)'));
1423
- console.log(chalk.green(' + soul-memory.md Living journal (grows with usage)'));
1424
- console.log(chalk.cyan(' Tip: Use @byan with the Forge workflow to build your soul interactively'));
1422
+ soulSpinner.succeed('Soul system installed (Creator mode — Yan\'s soul active)');
1423
+ console.log(chalk.green(' + soul.md — Yan\'s soul (active)'));
1424
+ console.log(chalk.green(' + tao.md — Yan\'s voice directives (active)'));
1425
+ console.log(chalk.green(' + soul-memory.md — Living journal'));
1426
+ console.log(chalk.green(' + creator-soul.md — Yan\'s original creator soul'));
1427
+ console.log(chalk.cyan(' Tip: Use @byan with the Forge workflow to build your own soul'));
1425
1428
 
1426
1429
  } else if (soulMode === 'blank') {
1427
1430
  // Copy blank templates only
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Domain-specific questions for Yanstaller Phase 2
3
+ * After generic 10 questions, ask personalized questions based on domain
4
+ */
5
+
6
+ const domainQuestions = {
7
+ web: [
8
+ {
9
+ name: 'framework',
10
+ message: 'Framework principal?',
11
+ type: 'list',
12
+ choices: ['React', 'Vue', 'Angular', 'Svelte', 'Next.js', 'Nuxt', 'Autre']
13
+ },
14
+ {
15
+ name: 'styling',
16
+ message: 'Approche CSS?',
17
+ type: 'list',
18
+ choices: ['Tailwind', 'CSS Modules', 'Styled Components', 'SASS/SCSS', 'Vanilla CSS']
19
+ },
20
+ {
21
+ name: 'stateManagement',
22
+ message: 'State management?',
23
+ type: 'list',
24
+ choices: ['Redux', 'Zustand', 'Pinia', 'Context API', 'Aucun', 'Autre']
25
+ },
26
+ {
27
+ name: 'testing',
28
+ message: 'Framework de test?',
29
+ type: 'list',
30
+ choices: ['Jest', 'Vitest', 'Playwright', 'Cypress', 'Testing Library', 'Aucun']
31
+ }
32
+ ],
33
+
34
+ 'backend/API': [
35
+ {
36
+ name: 'language',
37
+ message: 'Langage backend?',
38
+ type: 'list',
39
+ choices: ['Node.js', 'Python', 'Go', 'Rust', 'Java', 'C#/.NET', 'PHP']
40
+ },
41
+ {
42
+ name: 'framework',
43
+ message: 'Framework?',
44
+ type: 'list',
45
+ choices: ['Express', 'Fastify', 'NestJS', 'FastAPI', 'Django', 'Flask', 'Gin', 'Autre']
46
+ },
47
+ {
48
+ name: 'database',
49
+ message: 'Base de données principale?',
50
+ type: 'list',
51
+ choices: ['PostgreSQL', 'MySQL', 'MongoDB', 'Redis', 'SQLite', 'DynamoDB', 'Autre']
52
+ },
53
+ {
54
+ name: 'apiStyle',
55
+ message: 'Style API?',
56
+ type: 'list',
57
+ choices: ['REST', 'GraphQL', 'gRPC', 'tRPC', 'WebSocket', 'Mixte']
58
+ }
59
+ ],
60
+
61
+ devops: [
62
+ {
63
+ name: 'cicd',
64
+ message: 'Outil CI/CD?',
65
+ type: 'list',
66
+ choices: ['GitHub Actions', 'GitLab CI', 'Jenkins', 'CircleCI', 'Azure DevOps', 'ArgoCD']
67
+ },
68
+ {
69
+ name: 'cloud',
70
+ message: 'Cloud provider?',
71
+ type: 'list',
72
+ choices: ['AWS', 'GCP', 'Azure', 'DigitalOcean', 'On-premise', 'Multi-cloud']
73
+ },
74
+ {
75
+ name: 'iac',
76
+ message: 'Infrastructure as Code?',
77
+ type: 'list',
78
+ choices: ['Terraform', 'Pulumi', 'CloudFormation', 'Ansible', 'Chef/Puppet', 'Aucun']
79
+ },
80
+ {
81
+ name: 'containerization',
82
+ message: 'Conteneurisation?',
83
+ type: 'list',
84
+ choices: ['Docker + Kubernetes', 'Docker Compose', 'Podman', 'ECS/Fargate', 'Aucun']
85
+ },
86
+ {
87
+ name: 'monitoring',
88
+ message: 'Monitoring/Observabilité?',
89
+ type: 'list',
90
+ choices: ['Prometheus + Grafana', 'Datadog', 'New Relic', 'CloudWatch', 'ELK Stack', 'Aucun']
91
+ }
92
+ ],
93
+
94
+ 'data/ML': [
95
+ {
96
+ name: 'focus',
97
+ message: 'Focus principal?',
98
+ type: 'list',
99
+ choices: ['Data Engineering', 'Machine Learning', 'Data Science', 'Analytics/BI', 'MLOps']
100
+ },
101
+ {
102
+ name: 'language',
103
+ message: 'Langage principal?',
104
+ type: 'list',
105
+ choices: ['Python', 'R', 'Scala', 'SQL', 'Julia']
106
+ },
107
+ {
108
+ name: 'framework',
109
+ message: 'Framework ML?',
110
+ type: 'list',
111
+ choices: ['PyTorch', 'TensorFlow', 'Scikit-learn', 'XGBoost', 'Hugging Face', 'Aucun']
112
+ },
113
+ {
114
+ name: 'dataStore',
115
+ message: 'Data store?',
116
+ type: 'list',
117
+ choices: ['Snowflake', 'BigQuery', 'Databricks', 'Redshift', 'PostgreSQL', 'Autre']
118
+ },
119
+ {
120
+ name: 'orchestration',
121
+ message: 'Orchestration data?',
122
+ type: 'list',
123
+ choices: ['Airflow', 'Prefect', 'Dagster', 'Luigi', 'dbt', 'Aucun']
124
+ }
125
+ ],
126
+
127
+ mobile: [
128
+ {
129
+ name: 'platform',
130
+ message: 'Plateforme cible?',
131
+ type: 'list',
132
+ choices: ['iOS + Android (cross-platform)', 'iOS natif', 'Android natif', 'PWA']
133
+ },
134
+ {
135
+ name: 'framework',
136
+ message: 'Framework?',
137
+ type: 'list',
138
+ choices: ['React Native', 'Flutter', 'Expo', 'Swift/SwiftUI', 'Kotlin', 'Ionic']
139
+ },
140
+ {
141
+ name: 'backend',
142
+ message: 'Backend mobile?',
143
+ type: 'list',
144
+ choices: ['Firebase', 'Supabase', 'AWS Amplify', 'Custom API', 'Appwrite']
145
+ },
146
+ {
147
+ name: 'distribution',
148
+ message: 'Distribution?',
149
+ type: 'list',
150
+ choices: ['App Store + Play Store', 'Enterprise (MDM)', 'TestFlight/Beta', 'Sideload']
151
+ }
152
+ ],
153
+
154
+ 'multi-domain': [
155
+ {
156
+ name: 'primaryDomain',
157
+ message: 'Domaine principal?',
158
+ type: 'list',
159
+ choices: ['Frontend', 'Backend', 'Fullstack', 'Infrastructure', 'Data']
160
+ },
161
+ {
162
+ name: 'secondaryDomain',
163
+ message: 'Domaine secondaire?',
164
+ type: 'list',
165
+ choices: ['Frontend', 'Backend', 'DevOps', 'Mobile', 'Data/ML', 'Aucun']
166
+ },
167
+ {
168
+ name: 'integration',
169
+ message: 'Niveau intégration?',
170
+ type: 'list',
171
+ choices: ['Monorepo', 'Microservices', 'Monolithe modulaire', 'Serverless']
172
+ }
173
+ ]
174
+ };
175
+
176
+ /**
177
+ * Get domain-specific questions based on selected domain
178
+ * @param {string} domain - The domain selected in Q8
179
+ * @returns {Array} Array of inquirer question objects
180
+ */
181
+ function getDomainQuestions(domain) {
182
+ const questions = domainQuestions[domain] || domainQuestions['multi-domain'];
183
+
184
+ // Add question numbers starting from 11
185
+ return questions.map((q, index) => ({
186
+ ...q,
187
+ message: `${11 + index}. ${q.message}`
188
+ }));
189
+ }
190
+
191
+ /**
192
+ * Build prompt for Phase 2 agent analysis
193
+ * @param {Object} genericAnswers - Answers from Q1-Q10
194
+ * @param {Object} domainAnswers - Answers from domain-specific questions
195
+ * @param {Object} detectedPlatforms - Detected AI platforms
196
+ * @returns {string} Prompt for agent
197
+ */
198
+ function buildPhase2Prompt(genericAnswers, domainAnswers, detectedPlatforms) {
199
+ return [
200
+ 'Analyse ce profil projet et génère une configuration d\'agents BYAN optimale.',
201
+ '',
202
+ '## Profil Générique',
203
+ `- Type: ${genericAnswers.projectType}`,
204
+ `- Objectifs: ${genericAnswers.objectives.join(', ')}`,
205
+ `- Équipe: ${genericAnswers.teamSize}`,
206
+ `- Expérience: ${genericAnswers.experience}`,
207
+ `- Méthodologie: ${genericAnswers.methodology}`,
208
+ `- Domaine: ${genericAnswers.domain}`,
209
+ `- Qualité: ${genericAnswers.quality}`,
210
+ '',
211
+ '## Détails Domaine',
212
+ ...Object.entries(domainAnswers).map(([k, v]) => `- ${k}: ${v}`),
213
+ '',
214
+ '## Plateformes',
215
+ `- Détectées: ${Object.entries(detectedPlatforms).filter(([,v]) => v).map(([k]) => k).join(', ')}`,
216
+ '',
217
+ '## Output attendu (JSON)',
218
+ 'Retourne UNIQUEMENT un JSON valide:',
219
+ '{',
220
+ ' "coreAgents": [{"name": "...", "role": "...", "expertise": [...], "complexity": "simple|medium|complex"}],',
221
+ ' "optionalAgents": [{"name": "...", "role": "...", "expertise": [...]}],',
222
+ ' "agentRelationships": [{"from": "...", "to": "...", "type": "triggers|blocks|informs|depends"}],',
223
+ ' "projectStructure": {"type": "monorepo|microservices|monolith", "folders": [...]},',
224
+ ' "customAgentsToCreate": [{"name": "...", "template": "analyst|dev|pm|custom", "focus": "..."}],',
225
+ ' "recommendedModel": "gpt-5-mini|claude-haiku|...",',
226
+ ' "rationale": "Brief explanation"',
227
+ '}'
228
+ ].join('\n');
229
+ }
230
+
231
+ module.exports = {
232
+ domainQuestions,
233
+ getDomainQuestions,
234
+ buildPhase2Prompt
235
+ };
package/lib/errors.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Custom Error Classes
3
+ *
4
+ * @module errors
5
+ */
6
+
7
+ class YanInstallerError extends Error {
8
+ constructor(message, options) {
9
+ super(message, options);
10
+ this.name = 'YanInstallerError';
11
+ }
12
+ }
13
+
14
+ class NodeVersionError extends YanInstallerError {
15
+ constructor(required, current) {
16
+ super(`Node.js ${required}+ required, got ${current}`);
17
+ this.name = 'NodeVersionError';
18
+ this.required = required;
19
+ this.current = current;
20
+ }
21
+ }
22
+
23
+ class PlatformNotFoundError extends YanInstallerError {
24
+ constructor(platform) {
25
+ super(`Platform not found: ${platform}`);
26
+ this.name = 'PlatformNotFoundError';
27
+ this.platform = platform;
28
+ }
29
+ }
30
+
31
+ class PermissionError extends YanInstallerError {
32
+ constructor(path) {
33
+ super(`Permission denied: ${path}`);
34
+ this.name = 'PermissionError';
35
+ this.path = path;
36
+ }
37
+ }
38
+
39
+ class ValidationError extends YanInstallerError {
40
+ constructor(message, failures) {
41
+ super(message);
42
+ this.name = 'ValidationError';
43
+ this.failures = failures;
44
+ }
45
+ }
46
+
47
+ class BackupError extends YanInstallerError {
48
+ constructor(message, options) {
49
+ super(message, options);
50
+ this.name = 'BackupError';
51
+ }
52
+ }
53
+
54
+ module.exports = {
55
+ YanInstallerError,
56
+ NodeVersionError,
57
+ PlatformNotFoundError,
58
+ PermissionError,
59
+ ValidationError,
60
+ BackupError
61
+ };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Exit Codes
3
+ *
4
+ * Standard exit codes for YANSTALLER CLI.
5
+ *
6
+ * @module exit-codes
7
+ */
8
+
9
+ module.exports = {
10
+ /**
11
+ * Success - Installation completed without errors
12
+ */
13
+ SUCCESS: 0,
14
+
15
+ /**
16
+ * Node.js version too old (< 18.0.0)
17
+ */
18
+ NODE_VERSION_ERROR: 1,
19
+
20
+ /**
21
+ * Permission denied (file system access)
22
+ */
23
+ PERMISSION_ERROR: 2,
24
+
25
+ /**
26
+ * Post-installation validation failed
27
+ */
28
+ VALIDATION_FAILED: 3,
29
+
30
+ /**
31
+ * Installation process failed
32
+ */
33
+ INSTALLATION_FAILED: 4,
34
+
35
+ /**
36
+ * Backup operation failed
37
+ */
38
+ BACKUP_FAILED: 5,
39
+
40
+ /**
41
+ * Platform not found or not supported
42
+ */
43
+ PLATFORM_ERROR: 6,
44
+
45
+ /**
46
+ * User cancelled installation
47
+ */
48
+ USER_CANCELLED: 7,
49
+
50
+ /**
51
+ * Unknown error
52
+ */
53
+ UNKNOWN_ERROR: 99
54
+ };