create-byan-agent 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/API-BYAN-V2.md +741 -0
  2. package/BMAD-QUICK-REFERENCE.md +370 -0
  3. package/CHANGELOG-v2.1.0.md +371 -0
  4. package/LICENSE +1 -1
  5. package/MIGRATION-v2.0-to-v2.1.md +430 -0
  6. package/README-BYAN-V2.md +446 -0
  7. package/README.md +264 -201
  8. package/install/.eslintrc.js +20 -0
  9. package/install/.prettierrc +7 -0
  10. package/install/BUGFIX-CHALK.md +173 -0
  11. package/install/BUGFIX-DOCUMENTATION-INDEX.md +299 -0
  12. package/install/BUGFIX-PATH-RESOLUTION.md +293 -0
  13. package/install/BUGFIX-QUICKSTART.md +184 -0
  14. package/install/BUGFIX-SUMMARY.txt +91 -0
  15. package/install/BUGFIX-VISUAL-SUMMARY.md +253 -0
  16. package/install/DEPLOYMENT-GUIDE-V2.md +431 -0
  17. package/install/DOCS-INDEX.md +261 -0
  18. package/install/GUIDE-INSTALLATION-BYAN-SIMPLE.md +1083 -0
  19. package/install/INSTALLER-V2-CHANGES.md +472 -0
  20. package/install/LICENSE +21 -0
  21. package/install/PUBLICATION-CHECKLIST.md +265 -0
  22. package/install/PUBLISH-GUIDE.md +190 -0
  23. package/install/QUICKSTART.md +311 -0
  24. package/install/README-NPM-PUBLISH.md +298 -0
  25. package/install/README-NPM-SHORT.md +298 -0
  26. package/install/README-NPM.md +433 -0
  27. package/install/README-RACHID.md +302 -0
  28. package/install/README-V2-INDEX.md +306 -0
  29. package/install/README.md +298 -0
  30. package/install/RESUME-EXECUTIF-YAN.md +408 -0
  31. package/install/UPDATE-SUMMARY.md +205 -0
  32. package/install/__tests__/integration/detection-flow.test.js +154 -0
  33. package/install/__tests__/platforms/claude-code.test.js +175 -0
  34. package/install/__tests__/platforms/codex.test.js +80 -0
  35. package/install/__tests__/platforms/copilot-cli.test.js +118 -0
  36. package/install/__tests__/platforms/vscode.test.js +67 -0
  37. package/install/__tests__/utils/file-utils.test.js +87 -0
  38. package/install/__tests__/utils/git-detector.test.js +80 -0
  39. package/install/__tests__/utils/logger.test.js +83 -0
  40. package/install/__tests__/utils/node-detector.test.js +71 -0
  41. package/install/__tests__/utils/os-detector.test.js +63 -0
  42. package/install/__tests__/utils/yaml-utils.test.js +85 -0
  43. package/install/__tests__/yanstaller/detector.test.js +210 -0
  44. package/install/coverage/clover.xml +219 -0
  45. package/install/coverage/coverage-final.json +13 -0
  46. package/install/coverage/lcov-report/base.css +224 -0
  47. package/install/coverage/lcov-report/block-navigation.js +87 -0
  48. package/install/coverage/lcov-report/favicon.png +0 -0
  49. package/install/coverage/lcov-report/index.html +146 -0
  50. package/install/coverage/lcov-report/lib/errors.js.html +268 -0
  51. package/install/coverage/lcov-report/lib/exit-codes.js.html +247 -0
  52. package/install/coverage/lcov-report/lib/index.html +131 -0
  53. package/install/coverage/lcov-report/lib/platforms/claude-code.js.html +343 -0
  54. package/install/coverage/lcov-report/lib/platforms/codex.js.html +361 -0
  55. package/install/coverage/lcov-report/lib/platforms/copilot-cli.js.html +454 -0
  56. package/install/coverage/lcov-report/lib/platforms/index.html +176 -0
  57. package/install/coverage/lcov-report/lib/platforms/index.js.html +127 -0
  58. package/install/coverage/lcov-report/lib/platforms/vscode.js.html +238 -0
  59. package/install/coverage/lcov-report/lib/utils/config-loader.js.html +322 -0
  60. package/install/coverage/lcov-report/lib/utils/file-utils.js.html +397 -0
  61. package/install/coverage/lcov-report/lib/utils/git-detector.js.html +190 -0
  62. package/install/coverage/lcov-report/lib/utils/index.html +206 -0
  63. package/install/coverage/lcov-report/lib/utils/logger.js.html +277 -0
  64. package/install/coverage/lcov-report/lib/utils/node-detector.js.html +259 -0
  65. package/install/coverage/lcov-report/lib/utils/os-detector.js.html +307 -0
  66. package/install/coverage/lcov-report/lib/utils/yaml-utils.js.html +346 -0
  67. package/install/coverage/lcov-report/lib/yanstaller/backuper.js.html +409 -0
  68. package/install/coverage/lcov-report/lib/yanstaller/detector.js.html +508 -0
  69. package/install/coverage/lcov-report/lib/yanstaller/index.html +236 -0
  70. package/install/coverage/lcov-report/lib/yanstaller/index.js.html +364 -0
  71. package/install/coverage/lcov-report/lib/yanstaller/installer.js.html +505 -0
  72. package/install/coverage/lcov-report/lib/yanstaller/interviewer.js.html +349 -0
  73. package/install/coverage/lcov-report/lib/yanstaller/recommender.js.html +379 -0
  74. package/install/coverage/lcov-report/lib/yanstaller/troubleshooter.js.html +352 -0
  75. package/install/coverage/lcov-report/lib/yanstaller/validator.js.html +679 -0
  76. package/install/coverage/lcov-report/lib/yanstaller/wizard.js.html +412 -0
  77. package/install/coverage/lcov-report/platforms/claude-code.js.html +343 -0
  78. package/install/coverage/lcov-report/platforms/codex.js.html +361 -0
  79. package/install/coverage/lcov-report/platforms/copilot-cli.js.html +454 -0
  80. package/install/coverage/lcov-report/platforms/index.html +176 -0
  81. package/install/coverage/lcov-report/platforms/index.js.html +127 -0
  82. package/install/coverage/lcov-report/platforms/vscode.js.html +238 -0
  83. package/install/coverage/lcov-report/prettify.css +1 -0
  84. package/install/coverage/lcov-report/prettify.js +2 -0
  85. package/install/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  86. package/install/coverage/lcov-report/sorter.js +210 -0
  87. package/install/coverage/lcov-report/utils/file-utils.js.html +397 -0
  88. package/install/coverage/lcov-report/utils/git-detector.js.html +190 -0
  89. package/install/coverage/lcov-report/utils/index.html +191 -0
  90. package/install/coverage/lcov-report/utils/logger.js.html +277 -0
  91. package/install/coverage/lcov-report/utils/node-detector.js.html +259 -0
  92. package/install/coverage/lcov-report/utils/os-detector.js.html +307 -0
  93. package/install/coverage/lcov-report/utils/yaml-utils.js.html +346 -0
  94. package/install/coverage/lcov-report/yanstaller/detector.js.html +508 -0
  95. package/install/coverage/lcov-report/yanstaller/index.html +116 -0
  96. package/install/coverage/lcov.info +414 -0
  97. package/install/install.sh +239 -0
  98. package/install/jest.config.js +33 -0
  99. package/install/lib/errors.js +61 -0
  100. package/install/lib/exit-codes.js +54 -0
  101. package/install/lib/platforms/claude-code.js +86 -0
  102. package/install/lib/platforms/codex.js +92 -0
  103. package/install/lib/platforms/copilot-cli.js +123 -0
  104. package/install/lib/platforms/index.js +14 -0
  105. package/install/lib/platforms/vscode.js +51 -0
  106. package/install/lib/utils/config-loader.js +79 -0
  107. package/install/lib/utils/file-utils.js +104 -0
  108. package/install/lib/utils/git-detector.js +35 -0
  109. package/install/lib/utils/logger.js +64 -0
  110. package/install/lib/utils/node-detector.js +58 -0
  111. package/install/lib/utils/os-detector.js +74 -0
  112. package/install/lib/utils/yaml-utils.js +87 -0
  113. package/install/lib/yanstaller/backuper.js +108 -0
  114. package/install/lib/yanstaller/detector.js +141 -0
  115. package/install/lib/yanstaller/index.js +93 -0
  116. package/install/lib/yanstaller/installer.js +140 -0
  117. package/install/lib/yanstaller/interviewer.js +88 -0
  118. package/install/lib/yanstaller/recommender.js +98 -0
  119. package/install/lib/yanstaller/troubleshooter.js +89 -0
  120. package/install/lib/yanstaller/validator.js +198 -0
  121. package/install/lib/yanstaller/wizard.js +109 -0
  122. package/install/package-npm.json +55 -0
  123. package/install/package.json +63 -0
  124. package/install/src/byan-v2/context/copilot-context.js +79 -0
  125. package/install/src/byan-v2/context/session-state.js +98 -0
  126. package/install/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  127. package/install/src/byan-v2/dispatcher/local-executor.js +221 -0
  128. package/install/src/byan-v2/dispatcher/task-router.js +122 -0
  129. package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  130. package/install/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  131. package/install/src/byan-v2/generation/agent-profile-validator.js +113 -0
  132. package/install/src/byan-v2/generation/profile-template.js +113 -0
  133. package/install/src/byan-v2/generation/templates/default-agent.md +49 -0
  134. package/install/src/byan-v2/generation/templates/test-template.md +1 -0
  135. package/install/src/byan-v2/index.js +199 -0
  136. package/install/src/byan-v2/observability/error-tracker.js +105 -0
  137. package/install/src/byan-v2/observability/logger.js +154 -0
  138. package/install/src/byan-v2/observability/metrics-collector.js +194 -0
  139. package/install/src/byan-v2/orchestrator/analysis-state.js +268 -0
  140. package/install/src/byan-v2/orchestrator/generation-state.js +340 -0
  141. package/install/src/byan-v2/orchestrator/interview-state.js +271 -0
  142. package/install/src/byan-v2/orchestrator/state-machine.js +204 -0
  143. package/install/src/core/cache/cache.js +126 -0
  144. package/install/src/core/context/context.js +86 -0
  145. package/install/src/core/dispatcher/dispatcher.js +135 -0
  146. package/install/src/core/worker-pool/worker-pool.js +194 -0
  147. package/install/src/core/workflow/workflow-executor.js +220 -0
  148. package/install/src/index.js +139 -0
  149. package/install/src/observability/dashboard/dashboard.js +191 -0
  150. package/install/src/observability/logger/structured-logger.js +254 -0
  151. package/install/src/observability/metrics/metrics-collector.js +325 -0
  152. package/install/switch-to-v2.sh +126 -0
  153. package/install/test-chalk-fix.sh +210 -0
  154. package/install/test-installer-v2.sh +204 -0
  155. package/install/test-path-resolution.sh +200 -0
  156. package/package.json +53 -33
  157. package/src/byan-v2/context/copilot-context.js +79 -0
  158. package/src/byan-v2/context/session-state.js +98 -0
  159. package/src/byan-v2/data/mantras.json +852 -0
  160. package/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
  161. package/src/byan-v2/dispatcher/five-whys-analyzer.js +310 -0
  162. package/src/byan-v2/dispatcher/local-executor.js +221 -0
  163. package/src/byan-v2/dispatcher/task-router.js +122 -0
  164. package/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
  165. package/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
  166. package/src/byan-v2/generation/agent-profile-validator.js +113 -0
  167. package/src/byan-v2/generation/mantra-validator.js +416 -0
  168. package/src/byan-v2/generation/profile-template.js +113 -0
  169. package/src/byan-v2/generation/templates/default-agent.md +49 -0
  170. package/src/byan-v2/generation/templates/test-template.md +1 -0
  171. package/src/byan-v2/index.js +652 -0
  172. package/src/byan-v2/integration/voice-integration.js +295 -0
  173. package/src/byan-v2/observability/error-tracker.js +105 -0
  174. package/src/byan-v2/observability/logger.js +154 -0
  175. package/src/byan-v2/observability/metrics-collector.js +194 -0
  176. package/src/byan-v2/orchestrator/active-listener.js +541 -0
  177. package/src/byan-v2/orchestrator/analysis-state.js +268 -0
  178. package/src/byan-v2/orchestrator/generation-state.js +340 -0
  179. package/src/byan-v2/orchestrator/glossary-builder.js +431 -0
  180. package/src/byan-v2/orchestrator/interview-state.js +353 -0
  181. package/src/byan-v2/orchestrator/state-machine.js +253 -0
  182. package/src/core/cache/cache.js +126 -0
  183. package/src/core/context/context.js +86 -0
  184. package/src/core/dispatcher/dispatcher.js +135 -0
  185. package/src/core/worker-pool/worker-pool.js +194 -0
  186. package/src/core/workflow/workflow-executor.js +220 -0
  187. package/src/index.js +139 -0
  188. package/src/observability/dashboard/dashboard.js +191 -0
  189. package/src/observability/logger/structured-logger.js +254 -0
  190. package/src/observability/metrics/metrics-collector.js +325 -0
  191. package/templates/.github/agents/bmad-agent-test-dynamic.md +0 -21
  192. package/templates/.github/agents/franck.md +0 -379
  193. /package/{CHANGELOG.md → install/CHANGELOG.md} +0 -0
  194. /package/{bin → install/bin}/create-byan-agent-backup.js +0 -0
  195. /package/{bin → install/bin}/create-byan-agent-fixed.js +0 -0
  196. /package/{bin → install/bin}/create-byan-agent-v2.js +0 -0
  197. /package/{bin → install/bin}/create-byan-agent.js +0 -0
  198. /package/{templates → install/templates}/.github/agents/bmad-agent-bmad-master.md +0 -0
  199. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-agent-builder.md +0 -0
  200. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-module-builder.md +0 -0
  201. /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -0
  202. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-analyst.md +0 -0
  203. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-architect.md +0 -0
  204. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-dev.md +0 -0
  205. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-pm.md +0 -0
  206. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -0
  207. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quinn.md +0 -0
  208. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-sm.md +0 -0
  209. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-tech-writer.md +0 -0
  210. /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-ux-designer.md +0 -0
  211. /package/{templates → install/templates}/.github/agents/bmad-agent-byan-test.md +0 -0
  212. /package/{templates → install/templates}/.github/agents/bmad-agent-byan.md +0 -0
  213. /package/{templates → install/templates}/.github/agents/bmad-agent-carmack.md +0 -0
  214. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -0
  215. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -0
  216. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -0
  217. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -0
  218. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-presentation-master.md +0 -0
  219. /package/{templates → install/templates}/.github/agents/bmad-agent-cis-storyteller.md +0 -0
  220. /package/{templates → install/templates}/.github/agents/bmad-agent-marc.md +0 -0
  221. /package/{templates → install/templates}/.github/agents/bmad-agent-patnote.md +0 -0
  222. /package/{templates → install/templates}/.github/agents/bmad-agent-rachid.md +0 -0
  223. /package/{templates → install/templates}/.github/agents/bmad-agent-tea-tea.md +0 -0
  224. /package/{templates → install/templates}/_bmad/bmb/agents/agent-builder.md +0 -0
  225. /package/{templates → install/templates}/_bmad/bmb/agents/byan-test.md +0 -0
  226. /package/{templates → install/templates}/_bmad/bmb/agents/byan.md +0 -0
  227. /package/{templates → install/templates}/_bmad/bmb/agents/marc.md +0 -0
  228. /package/{templates → install/templates}/_bmad/bmb/agents/module-builder.md +0 -0
  229. /package/{templates → install/templates}/_bmad/bmb/agents/patnote.md +0 -0
  230. /package/{templates → install/templates}/_bmad/bmb/agents/rachid.md +0 -0
  231. /package/{templates → install/templates}/_bmad/bmb/agents/workflow-builder.md +0 -0
  232. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -0
  233. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/templates.yaml +0 -0
  234. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -0
  235. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -0
  236. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/interview-workflow.md +0 -0
  237. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -0
  238. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -0
  239. /package/{templates → install/templates}/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -0
  240. /package/{templates → install/templates}/_bmad/core/agents/carmack.md +0 -0
@@ -0,0 +1,652 @@
1
+ const SessionState = require('./context/session-state');
2
+ const TaskRouter = require('./dispatcher/task-router');
3
+ const StateMachine = require('./orchestrator/state-machine');
4
+ const InterviewState = require('./orchestrator/interview-state');
5
+ const AnalysisState = require('./orchestrator/analysis-state');
6
+ const GenerationState = require('./orchestrator/generation-state');
7
+ const Logger = require('./observability/logger');
8
+ const MetricsCollector = require('./observability/metrics-collector');
9
+
10
+ // v2.1.0: BMAD modules integration
11
+ const GlossaryBuilder = require('./orchestrator/glossary-builder');
12
+ const FiveWhysAnalyzer = require('./dispatcher/five-whys-analyzer');
13
+ const ActiveListener = require('./orchestrator/active-listener');
14
+ const MantraValidator = require('./generation/mantra-validator');
15
+ const VoiceIntegration = require('./integration/voice-integration');
16
+
17
+ const crypto = require('crypto');
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+
21
+ class ByanV2 {
22
+ constructor(config = {}) {
23
+ this.config = this._loadConfig(config);
24
+
25
+ if (config.sessionState) {
26
+ this.sessionState = config.sessionState;
27
+ } else {
28
+ const sessionId = this.config.sessionId || crypto.randomUUID();
29
+ this.sessionState = new SessionState(sessionId);
30
+ }
31
+
32
+ if (config.logger) {
33
+ this.logger = config.logger;
34
+ } else {
35
+ this.logger = new Logger();
36
+ }
37
+
38
+ this.metrics = new MetricsCollector();
39
+ this.dispatcher = new TaskRouter();
40
+
41
+ const ErrorTracker = require('./observability/error-tracker');
42
+ this.errorTracker = new ErrorTracker();
43
+
44
+ if (config.stateMachine) {
45
+ this.stateMachine = config.stateMachine;
46
+ } else {
47
+ this.stateMachine = new StateMachine({
48
+ logger: this.logger,
49
+ errorTracker: this.errorTracker
50
+ });
51
+
52
+ this.interviewState = new InterviewState(this.sessionState);
53
+ this.analysisState = new AnalysisState(this.sessionState);
54
+ this.generationState = new GenerationState(this.sessionState);
55
+ }
56
+
57
+ // v2.1.0: Initialize BMAD modules
58
+ this._initializeBMADModules(config);
59
+ }
60
+
61
+ /**
62
+ * v2.1.0: Initialize BMAD feature modules
63
+ * @private
64
+ */
65
+ _initializeBMADModules(config) {
66
+ const bmadConfig = this.config.bmad_features || {};
67
+
68
+ // GlossaryBuilder
69
+ if (bmadConfig.glossary?.enabled !== false) {
70
+ this.glossaryBuilder = new GlossaryBuilder(this.sessionState, this.logger);
71
+ if (bmadConfig.glossary?.min_concepts) {
72
+ this.glossaryBuilder.minConcepts = bmadConfig.glossary.min_concepts;
73
+ }
74
+ if (bmadConfig.glossary?.validation?.min_definition_length) {
75
+ this.glossaryBuilder.minDefinitionLength = bmadConfig.glossary.validation.min_definition_length;
76
+ }
77
+ if (bmadConfig.glossary?.validation?.clarity_threshold) {
78
+ this.glossaryBuilder.clarityThreshold = bmadConfig.glossary.validation.clarity_threshold;
79
+ }
80
+ }
81
+
82
+ // FiveWhysAnalyzer
83
+ if (bmadConfig.five_whys?.enabled !== false) {
84
+ this.fiveWhysAnalyzer = new FiveWhysAnalyzer(this.sessionState, this.logger);
85
+ if (bmadConfig.five_whys?.max_depth) {
86
+ this.fiveWhysAnalyzer.maxDepth = bmadConfig.five_whys.max_depth;
87
+ }
88
+ if (bmadConfig.five_whys?.pain_keywords) {
89
+ this.fiveWhysAnalyzer.painKeywords = bmadConfig.five_whys.pain_keywords;
90
+ }
91
+ }
92
+
93
+ // ActiveListener
94
+ if (bmadConfig.active_listening?.enabled !== false) {
95
+ this.activeListener = new ActiveListener(this.sessionState, this.logger);
96
+ if (bmadConfig.active_listening?.reformulate_every) {
97
+ this.activeListener.validationFrequency = bmadConfig.active_listening.reformulate_every;
98
+ }
99
+ }
100
+
101
+ // MantraValidator
102
+ if (bmadConfig.mantras?.validate !== false) {
103
+ try {
104
+ const mantrasPath = config.mantrasPath || path.join(__dirname, 'data/mantras.json');
105
+ if (fs.existsSync(mantrasPath)) {
106
+ const mantrasData = JSON.parse(fs.readFileSync(mantrasPath, 'utf8'));
107
+ this.mantraValidator = new MantraValidator(mantrasData);
108
+ } else {
109
+ this.mantraValidator = new MantraValidator();
110
+ }
111
+
112
+ this.mantraValidatorConfig = {
113
+ minScore: bmadConfig.mantras?.min_score || 80,
114
+ enforceOnGeneration: bmadConfig.mantras?.enforce_on_generation !== false,
115
+ failOnLowScore: bmadConfig.mantras?.fail_on_low_score || false
116
+ };
117
+ } catch (error) {
118
+ this.logger.warn('Failed to initialize MantraValidator', { error: error.message });
119
+ }
120
+ }
121
+
122
+ // VoiceIntegration
123
+ if (bmadConfig.voice_integration?.enabled !== false) {
124
+ this.voiceIntegration = new VoiceIntegration(this.sessionState, this.logger);
125
+
126
+ // Initialize asynchronously (non-blocking)
127
+ this.voiceIntegration.initialize().then(success => {
128
+ if (success) {
129
+ this.logger.info('[ByanV2] Voice integration enabled');
130
+ } else {
131
+ this.logger.debug('[ByanV2] Voice integration not available');
132
+ }
133
+ }).catch(error => {
134
+ this.logger.warn('[ByanV2] Voice integration init failed', { error: error.message });
135
+ });
136
+ }
137
+
138
+ this.logger.info('BMAD modules initialized', {
139
+ glossary: !!this.glossaryBuilder,
140
+ fiveWhys: !!this.fiveWhysAnalyzer,
141
+ activeListener: !!this.activeListener,
142
+ mantraValidator: !!this.mantraValidator,
143
+ voiceIntegration: !!this.voiceIntegration
144
+ });
145
+ }
146
+
147
+ _loadConfig(customConfig) {
148
+ const defaults = {
149
+ maxQuestions: 12,
150
+ complexityThresholds: {
151
+ low: 30,
152
+ medium: 60
153
+ },
154
+ outputDir: './_byan-output',
155
+ env: customConfig.env || (process.env.GITHUB_COPILOT ? 'copilot' : 'standalone')
156
+ };
157
+
158
+ return { ...defaults, ...customConfig };
159
+ }
160
+
161
+ isCopilotContext() {
162
+ return this.config.env === 'copilot' || process.env.GITHUB_COPILOT === 'true';
163
+ }
164
+
165
+ async startSession() {
166
+ this.logger.info('Starting BYAN session', {
167
+ event: 'session_start',
168
+ sessionId: this.sessionState.sessionId
169
+ });
170
+
171
+ this.metrics.increment('sessionsStarted');
172
+
173
+ await this.stateMachine.transition('INTERVIEW');
174
+
175
+ this.logger.info('State transition', {
176
+ event: 'state_transition',
177
+ from: 'INIT',
178
+ to: 'INTERVIEW'
179
+ });
180
+
181
+ return this.sessionState.sessionId;
182
+ }
183
+
184
+ async getNextQuestion() {
185
+ const currentState = this.stateMachine.getCurrentState();
186
+
187
+ if (currentState.name !== 'INTERVIEW') {
188
+ throw new Error('Not in INTERVIEW state');
189
+ }
190
+
191
+ const question = this.interviewState.askNextQuestion();
192
+
193
+ this.metrics.increment('questionsAsked');
194
+
195
+ return typeof question === 'string' ? question : question?.text || question;
196
+ }
197
+
198
+ async submitResponse(response) {
199
+ if (!response || response.trim().length === 0) {
200
+ this.metrics.increment('errors');
201
+ throw new Error('Response cannot be empty');
202
+ }
203
+
204
+ const sanitized = response.substring(0, 100);
205
+ this.logger.info('User response received', {
206
+ event: 'response_submitted',
207
+ response: sanitized
208
+ });
209
+
210
+ // v2.1.0: Active listening integration
211
+ let processedResponse = response;
212
+ if (this.activeListener) {
213
+ const listenResult = await this.listen(response);
214
+ if (listenResult.valid) {
215
+ processedResponse = listenResult.reformulated || response;
216
+
217
+ // Check if Five Whys should be triggered
218
+ if (this.fiveWhysAnalyzer && this.config.bmad_features?.five_whys?.auto_trigger) {
219
+ const painCheck = await this.detectPainPoints(response);
220
+ if (painCheck.hasPainPoints) {
221
+ const whysResult = await this.startFiveWhys(response);
222
+ // Store Five Whys context for later use
223
+ this.sessionState.context.fiveWhysActive = whysResult.needsWhys;
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ const currentState = this.stateMachine.getCurrentState();
230
+
231
+ if (currentState.name === 'INTERVIEW') {
232
+ const isComplete = this.interviewState.processResponse(processedResponse);
233
+
234
+ if (isComplete) {
235
+ // v2.1.0: Check if glossary should be triggered
236
+ const shouldTriggerGlossary = this._shouldTriggerGlossary();
237
+
238
+ if (shouldTriggerGlossary && this.glossaryBuilder) {
239
+ await this.stateMachine.transition('GLOSSARY');
240
+ this.logger.info('Glossary triggered for domain', {
241
+ domain: this.sessionState.context.domain || 'unknown'
242
+ });
243
+ } else {
244
+ await this.stateMachine.transition('ANALYSIS');
245
+ }
246
+
247
+ this.logger.info('State transition', {
248
+ event: 'state_transition',
249
+ from: 'INTERVIEW',
250
+ to: shouldTriggerGlossary ? 'GLOSSARY' : 'ANALYSIS'
251
+ });
252
+ }
253
+ }
254
+
255
+ return { success: true };
256
+ }
257
+
258
+ /**
259
+ * v2.1.0: Determine if glossary should be triggered
260
+ * @private
261
+ */
262
+ _shouldTriggerGlossary() {
263
+ const glossaryConfig = this.config.bmad_features?.glossary;
264
+ if (!glossaryConfig || !glossaryConfig.enabled) {
265
+ return false;
266
+ }
267
+
268
+ const domain = this.sessionState.context.domain || '';
269
+ const autoTriggerDomains = glossaryConfig.auto_trigger_domains || [];
270
+
271
+ return autoTriggerDomains.some(triggerDomain =>
272
+ domain.toLowerCase().includes(triggerDomain.toLowerCase())
273
+ );
274
+ }
275
+
276
+ async generateProfile() {
277
+ const currentState = this.stateMachine.getCurrentState();
278
+
279
+ // Transition to GENERATION state if not already there
280
+ if (currentState.name === 'INTERVIEW') {
281
+ await this.stateMachine.transition('ANALYSIS');
282
+ await this.stateMachine.transition('GENERATION');
283
+ } else if (currentState.name === 'ANALYSIS') {
284
+ await this.stateMachine.transition('GENERATION');
285
+ } else if (currentState.name === 'GLOSSARY') {
286
+ await this.stateMachine.transition('ANALYSIS');
287
+ await this.stateMachine.transition('GENERATION');
288
+ } else if (currentState.name !== 'GENERATION') {
289
+ this.metrics.increment('errors');
290
+ throw new Error('Cannot generate profile in current state');
291
+ }
292
+
293
+ this.logger.info('Generating agent profile', {
294
+ event: 'profile_generation_start'
295
+ });
296
+
297
+ const profile = await this.generationState.generateProfile();
298
+
299
+ this.metrics.increment('profilesGenerated');
300
+
301
+ // v2.1.0: Mantra validation integration
302
+ const shouldValidate = this.mantraValidator &&
303
+ this.mantraValidatorConfig?.enforceOnGeneration;
304
+
305
+ if (shouldValidate) {
306
+ await this.stateMachine.transition('VALIDATION');
307
+
308
+ this.logger.info('Validating agent profile', {
309
+ event: 'validation_start'
310
+ });
311
+
312
+ const validationResults = await this.validateAgent(profile);
313
+
314
+ // Store validation results
315
+ // If profile is string, create metadata object; if object, add to it
316
+ const validationMetadata = {
317
+ timestamp: validationResults.timestamp,
318
+ score: validationResults.score,
319
+ compliant: validationResults.compliant.length,
320
+ nonCompliant: validationResults.nonCompliant.length,
321
+ errors: validationResults.errors,
322
+ warnings: validationResults.warnings
323
+ };
324
+
325
+ // Only add validation to profile if it's an object
326
+ if (typeof profile === 'object' && profile !== null) {
327
+ profile.validation = validationMetadata;
328
+ } else {
329
+ // Store in session state context for later retrieval
330
+ this.sessionState.context.profileValidation = validationMetadata;
331
+ }
332
+
333
+ // Check if validation passes threshold
334
+ if (validationResults.score < this.mantraValidatorConfig.minScore) {
335
+ this.logger.warn('Agent validation below threshold', {
336
+ score: validationResults.score,
337
+ threshold: this.mantraValidatorConfig.minScore
338
+ });
339
+
340
+ if (this.mantraValidatorConfig.failOnLowScore) {
341
+ await this.stateMachine.transition('ERROR');
342
+ throw new Error(
343
+ `Agent validation failed: score ${validationResults.score} < ${this.mantraValidatorConfig.minScore}`
344
+ );
345
+ }
346
+ }
347
+
348
+ this.logger.info('Validation complete', {
349
+ event: 'validation_complete',
350
+ score: validationResults.score
351
+ });
352
+ }
353
+
354
+ await this.stateMachine.transition('COMPLETED');
355
+
356
+ this.logger.info('Profile generation complete', {
357
+ event: 'profile_generation_complete'
358
+ });
359
+
360
+ return profile;
361
+ }
362
+
363
+ async endSession() {
364
+ const currentState = this.stateMachine.getCurrentState();
365
+
366
+ if (currentState.name !== 'COMPLETED' && currentState.name !== 'ERROR') {
367
+ // Force transition through states if needed
368
+ if (currentState.name === 'INTERVIEW') {
369
+ await this.stateMachine.transition('ANALYSIS');
370
+ await this.stateMachine.transition('GENERATION');
371
+ } else if (currentState.name === 'ANALYSIS') {
372
+ await this.stateMachine.transition('GENERATION');
373
+ }
374
+
375
+ if (this.stateMachine.getCurrentState().name === 'GENERATION') {
376
+ await this.stateMachine.transition('COMPLETED');
377
+ }
378
+ }
379
+
380
+ this.logger.info('Session ended', {
381
+ event: 'session_end',
382
+ sessionId: this.sessionState.sessionId
383
+ });
384
+
385
+ return { success: true };
386
+ }
387
+
388
+ getMetricsSummary() {
389
+ return this.metrics.getSummary();
390
+ }
391
+
392
+ // ========================================
393
+ // v2.1.0: BMAD Module Public Methods
394
+ // ========================================
395
+
396
+ // --- GlossaryBuilder Methods ---
397
+
398
+ /**
399
+ * Start glossary building session
400
+ * @returns {Object} Prompt and instructions
401
+ */
402
+ async startGlossary() {
403
+ if (!this.glossaryBuilder) {
404
+ throw new Error('GlossaryBuilder not initialized');
405
+ }
406
+
407
+ const result = this.glossaryBuilder.start();
408
+ this.logger.info('Glossary session started');
409
+
410
+ // Transition to GLOSSARY state if in INTERVIEW
411
+ const currentState = this.stateMachine.getCurrentState();
412
+ if (currentState.name === 'INTERVIEW') {
413
+ await this.stateMachine.transition('GLOSSARY');
414
+ }
415
+
416
+ return result;
417
+ }
418
+
419
+ /**
420
+ * Add concept to glossary
421
+ * @param {string} name - Concept name
422
+ * @param {string} definition - Concept definition
423
+ * @returns {Object} Validation result with suggestions
424
+ */
425
+ async addConcept(name, definition) {
426
+ if (!this.glossaryBuilder) {
427
+ throw new Error('GlossaryBuilder not initialized');
428
+ }
429
+
430
+ return this.glossaryBuilder.addConcept(name, definition);
431
+ }
432
+
433
+ /**
434
+ * Check if glossary is complete
435
+ * @returns {boolean} True if minimum concepts met
436
+ */
437
+ async isGlossaryComplete() {
438
+ if (!this.glossaryBuilder) {
439
+ return true; // If not enabled, consider complete
440
+ }
441
+
442
+ return this.glossaryBuilder.isComplete();
443
+ }
444
+
445
+ /**
446
+ * Export glossary data
447
+ * @returns {Object} Complete glossary with metadata
448
+ */
449
+ async exportGlossary() {
450
+ if (!this.glossaryBuilder) {
451
+ throw new Error('GlossaryBuilder not initialized');
452
+ }
453
+
454
+ return this.glossaryBuilder.export();
455
+ }
456
+
457
+ // --- FiveWhysAnalyzer Methods ---
458
+
459
+ /**
460
+ * Detect pain points in user response
461
+ * @param {string} response - User response text
462
+ * @returns {Object} Detection result with pain points
463
+ */
464
+ async detectPainPoints(response) {
465
+ if (!this.fiveWhysAnalyzer) {
466
+ return { hasPainPoints: false, reason: 'FiveWhysAnalyzer not initialized' };
467
+ }
468
+
469
+ return this.fiveWhysAnalyzer._detectPainPoints(response);
470
+ }
471
+
472
+ /**
473
+ * Start Five Whys analysis
474
+ * @param {string} response - Initial response with pain point
475
+ * @returns {Object} Analysis start result with first question
476
+ */
477
+ async startFiveWhys(response) {
478
+ if (!this.fiveWhysAnalyzer) {
479
+ throw new Error('FiveWhysAnalyzer not initialized');
480
+ }
481
+
482
+ const result = this.fiveWhysAnalyzer.start(response);
483
+
484
+ if (result.needsWhys) {
485
+ this.logger.info('Five Whys analysis started', {
486
+ painPoints: result.painPoints.length
487
+ });
488
+ }
489
+
490
+ return result;
491
+ }
492
+
493
+ /**
494
+ * Process answer to WHY question
495
+ * @param {string} answer - User's answer
496
+ * @returns {Object} Next question or completion
497
+ */
498
+ async processWhyAnswer(answer) {
499
+ if (!this.fiveWhysAnalyzer) {
500
+ throw new Error('FiveWhysAnalyzer not initialized');
501
+ }
502
+
503
+ const result = this.fiveWhysAnalyzer.answer(answer);
504
+
505
+ if (result.complete) {
506
+ this.logger.info('Five Whys analysis complete', {
507
+ depth: result.depth,
508
+ rootCause: result.rootCause
509
+ });
510
+ }
511
+
512
+ return result;
513
+ }
514
+
515
+ /**
516
+ * Get root cause from analysis
517
+ * @returns {Object|null} Root cause or null if not complete
518
+ */
519
+ async getRootCause() {
520
+ if (!this.fiveWhysAnalyzer) {
521
+ return null;
522
+ }
523
+
524
+ return this.fiveWhysAnalyzer.getRootCause();
525
+ }
526
+
527
+ // --- ActiveListener Methods ---
528
+
529
+ /**
530
+ * Process response through active listening
531
+ * @param {string} userResponse - Raw user input
532
+ * @returns {Object} Listening result with reformulation
533
+ */
534
+ async listen(userResponse) {
535
+ if (!this.activeListener) {
536
+ return { valid: true, original: userResponse }; // Pass-through if disabled
537
+ }
538
+
539
+ const result = this.activeListener.listen(userResponse);
540
+
541
+ if (result.valid) {
542
+ this.logger.info('Active listening processed', {
543
+ clarityScore: result.clarityScore,
544
+ needsValidation: result.needsValidation
545
+ });
546
+ }
547
+
548
+ return result;
549
+ }
550
+
551
+ /**
552
+ * Reformulate text for clarity
553
+ * @param {string} text - Text to reformulate
554
+ * @returns {Object} Reformulated text with clarity score
555
+ */
556
+ async reformulate(text) {
557
+ if (!this.activeListener) {
558
+ return { text, clarityScore: 1.0 };
559
+ }
560
+
561
+ return this.activeListener.reformulate(text);
562
+ }
563
+
564
+ /**
565
+ * Check if validation needed
566
+ * @returns {boolean} True if validation should occur
567
+ */
568
+ async needsValidation() {
569
+ if (!this.activeListener) {
570
+ return false;
571
+ }
572
+
573
+ return this.activeListener.needsValidation();
574
+ }
575
+
576
+ /**
577
+ * Validate understanding with user
578
+ * @param {boolean} confirmation - User confirmation
579
+ * @returns {Object} Validation result
580
+ */
581
+ async validateUnderstanding(confirmation) {
582
+ if (!this.activeListener) {
583
+ return { validated: true };
584
+ }
585
+
586
+ const summary = this.activeListener.getSummary();
587
+
588
+ return {
589
+ validated: confirmation,
590
+ summary: summary,
591
+ needsCorrection: !confirmation
592
+ };
593
+ }
594
+
595
+ // --- MantraValidator Methods ---
596
+
597
+ /**
598
+ * Validate agent definition against mantras
599
+ * @param {Object|string} agentDefinition - Agent to validate
600
+ * @returns {Object} Validation results with compliance score
601
+ */
602
+ async validateAgent(agentDefinition) {
603
+ if (!this.mantraValidator) {
604
+ throw new Error('MantraValidator not initialized');
605
+ }
606
+
607
+ const results = this.mantraValidator.validate(agentDefinition);
608
+
609
+ this.logger.info('Agent validated', {
610
+ score: results.score,
611
+ compliant: results.compliant.length,
612
+ nonCompliant: results.nonCompliant.length
613
+ });
614
+
615
+ return results;
616
+ }
617
+
618
+ /**
619
+ * Get compliance score from last validation
620
+ * @returns {number|null} Compliance score (0-100) or null
621
+ */
622
+ async getComplianceScore() {
623
+ if (!this.mantraValidator || !this.mantraValidator.results) {
624
+ return null;
625
+ }
626
+
627
+ return this.mantraValidator.results.score;
628
+ }
629
+
630
+ /**
631
+ * Get detailed compliance report
632
+ * @returns {Object} Full validation report
633
+ */
634
+ async getComplianceReport() {
635
+ if (!this.mantraValidator || !this.mantraValidator.results) {
636
+ return null;
637
+ }
638
+
639
+ return this.mantraValidator.getReport();
640
+ }
641
+
642
+ async getSessionSummary() {
643
+ return {
644
+ sessionId: this.sessionState.sessionId,
645
+ questionsAsked: this.sessionState.userResponses.length,
646
+ state: this.stateMachine.getCurrentState().name,
647
+ timestamp: new Date().toISOString()
648
+ };
649
+ }
650
+ }
651
+
652
+ module.exports = ByanV2;