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.
- package/API-BYAN-V2.md +741 -0
- package/BMAD-QUICK-REFERENCE.md +370 -0
- package/CHANGELOG-v2.1.0.md +371 -0
- package/LICENSE +1 -1
- package/MIGRATION-v2.0-to-v2.1.md +430 -0
- package/README-BYAN-V2.md +446 -0
- package/README.md +264 -201
- package/install/.eslintrc.js +20 -0
- package/install/.prettierrc +7 -0
- package/install/BUGFIX-CHALK.md +173 -0
- package/install/BUGFIX-DOCUMENTATION-INDEX.md +299 -0
- package/install/BUGFIX-PATH-RESOLUTION.md +293 -0
- package/install/BUGFIX-QUICKSTART.md +184 -0
- package/install/BUGFIX-SUMMARY.txt +91 -0
- package/install/BUGFIX-VISUAL-SUMMARY.md +253 -0
- package/install/DEPLOYMENT-GUIDE-V2.md +431 -0
- package/install/DOCS-INDEX.md +261 -0
- package/install/GUIDE-INSTALLATION-BYAN-SIMPLE.md +1083 -0
- package/install/INSTALLER-V2-CHANGES.md +472 -0
- package/install/LICENSE +21 -0
- package/install/PUBLICATION-CHECKLIST.md +265 -0
- package/install/PUBLISH-GUIDE.md +190 -0
- package/install/QUICKSTART.md +311 -0
- package/install/README-NPM-PUBLISH.md +298 -0
- package/install/README-NPM-SHORT.md +298 -0
- package/install/README-NPM.md +433 -0
- package/install/README-RACHID.md +302 -0
- package/install/README-V2-INDEX.md +306 -0
- package/install/README.md +298 -0
- package/install/RESUME-EXECUTIF-YAN.md +408 -0
- package/install/UPDATE-SUMMARY.md +205 -0
- package/install/__tests__/integration/detection-flow.test.js +154 -0
- package/install/__tests__/platforms/claude-code.test.js +175 -0
- package/install/__tests__/platforms/codex.test.js +80 -0
- package/install/__tests__/platforms/copilot-cli.test.js +118 -0
- package/install/__tests__/platforms/vscode.test.js +67 -0
- package/install/__tests__/utils/file-utils.test.js +87 -0
- package/install/__tests__/utils/git-detector.test.js +80 -0
- package/install/__tests__/utils/logger.test.js +83 -0
- package/install/__tests__/utils/node-detector.test.js +71 -0
- package/install/__tests__/utils/os-detector.test.js +63 -0
- package/install/__tests__/utils/yaml-utils.test.js +85 -0
- package/install/__tests__/yanstaller/detector.test.js +210 -0
- package/install/coverage/clover.xml +219 -0
- package/install/coverage/coverage-final.json +13 -0
- package/install/coverage/lcov-report/base.css +224 -0
- package/install/coverage/lcov-report/block-navigation.js +87 -0
- package/install/coverage/lcov-report/favicon.png +0 -0
- package/install/coverage/lcov-report/index.html +146 -0
- package/install/coverage/lcov-report/lib/errors.js.html +268 -0
- package/install/coverage/lcov-report/lib/exit-codes.js.html +247 -0
- package/install/coverage/lcov-report/lib/index.html +131 -0
- package/install/coverage/lcov-report/lib/platforms/claude-code.js.html +343 -0
- package/install/coverage/lcov-report/lib/platforms/codex.js.html +361 -0
- package/install/coverage/lcov-report/lib/platforms/copilot-cli.js.html +454 -0
- package/install/coverage/lcov-report/lib/platforms/index.html +176 -0
- package/install/coverage/lcov-report/lib/platforms/index.js.html +127 -0
- package/install/coverage/lcov-report/lib/platforms/vscode.js.html +238 -0
- package/install/coverage/lcov-report/lib/utils/config-loader.js.html +322 -0
- package/install/coverage/lcov-report/lib/utils/file-utils.js.html +397 -0
- package/install/coverage/lcov-report/lib/utils/git-detector.js.html +190 -0
- package/install/coverage/lcov-report/lib/utils/index.html +206 -0
- package/install/coverage/lcov-report/lib/utils/logger.js.html +277 -0
- package/install/coverage/lcov-report/lib/utils/node-detector.js.html +259 -0
- package/install/coverage/lcov-report/lib/utils/os-detector.js.html +307 -0
- package/install/coverage/lcov-report/lib/utils/yaml-utils.js.html +346 -0
- package/install/coverage/lcov-report/lib/yanstaller/backuper.js.html +409 -0
- package/install/coverage/lcov-report/lib/yanstaller/detector.js.html +508 -0
- package/install/coverage/lcov-report/lib/yanstaller/index.html +236 -0
- package/install/coverage/lcov-report/lib/yanstaller/index.js.html +364 -0
- package/install/coverage/lcov-report/lib/yanstaller/installer.js.html +505 -0
- package/install/coverage/lcov-report/lib/yanstaller/interviewer.js.html +349 -0
- package/install/coverage/lcov-report/lib/yanstaller/recommender.js.html +379 -0
- package/install/coverage/lcov-report/lib/yanstaller/troubleshooter.js.html +352 -0
- package/install/coverage/lcov-report/lib/yanstaller/validator.js.html +679 -0
- package/install/coverage/lcov-report/lib/yanstaller/wizard.js.html +412 -0
- package/install/coverage/lcov-report/platforms/claude-code.js.html +343 -0
- package/install/coverage/lcov-report/platforms/codex.js.html +361 -0
- package/install/coverage/lcov-report/platforms/copilot-cli.js.html +454 -0
- package/install/coverage/lcov-report/platforms/index.html +176 -0
- package/install/coverage/lcov-report/platforms/index.js.html +127 -0
- package/install/coverage/lcov-report/platforms/vscode.js.html +238 -0
- package/install/coverage/lcov-report/prettify.css +1 -0
- package/install/coverage/lcov-report/prettify.js +2 -0
- package/install/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/install/coverage/lcov-report/sorter.js +210 -0
- package/install/coverage/lcov-report/utils/file-utils.js.html +397 -0
- package/install/coverage/lcov-report/utils/git-detector.js.html +190 -0
- package/install/coverage/lcov-report/utils/index.html +191 -0
- package/install/coverage/lcov-report/utils/logger.js.html +277 -0
- package/install/coverage/lcov-report/utils/node-detector.js.html +259 -0
- package/install/coverage/lcov-report/utils/os-detector.js.html +307 -0
- package/install/coverage/lcov-report/utils/yaml-utils.js.html +346 -0
- package/install/coverage/lcov-report/yanstaller/detector.js.html +508 -0
- package/install/coverage/lcov-report/yanstaller/index.html +116 -0
- package/install/coverage/lcov.info +414 -0
- package/install/install.sh +239 -0
- package/install/jest.config.js +33 -0
- package/install/lib/errors.js +61 -0
- package/install/lib/exit-codes.js +54 -0
- package/install/lib/platforms/claude-code.js +86 -0
- package/install/lib/platforms/codex.js +92 -0
- package/install/lib/platforms/copilot-cli.js +123 -0
- package/install/lib/platforms/index.js +14 -0
- package/install/lib/platforms/vscode.js +51 -0
- package/install/lib/utils/config-loader.js +79 -0
- package/install/lib/utils/file-utils.js +104 -0
- package/install/lib/utils/git-detector.js +35 -0
- package/install/lib/utils/logger.js +64 -0
- package/install/lib/utils/node-detector.js +58 -0
- package/install/lib/utils/os-detector.js +74 -0
- package/install/lib/utils/yaml-utils.js +87 -0
- package/install/lib/yanstaller/backuper.js +108 -0
- package/install/lib/yanstaller/detector.js +141 -0
- package/install/lib/yanstaller/index.js +93 -0
- package/install/lib/yanstaller/installer.js +140 -0
- package/install/lib/yanstaller/interviewer.js +88 -0
- package/install/lib/yanstaller/recommender.js +98 -0
- package/install/lib/yanstaller/troubleshooter.js +89 -0
- package/install/lib/yanstaller/validator.js +198 -0
- package/install/lib/yanstaller/wizard.js +109 -0
- package/install/package-npm.json +55 -0
- package/install/package.json +63 -0
- package/install/src/byan-v2/context/copilot-context.js +79 -0
- package/install/src/byan-v2/context/session-state.js +98 -0
- package/install/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
- package/install/src/byan-v2/dispatcher/local-executor.js +221 -0
- package/install/src/byan-v2/dispatcher/task-router.js +122 -0
- package/install/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
- package/install/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
- package/install/src/byan-v2/generation/agent-profile-validator.js +113 -0
- package/install/src/byan-v2/generation/profile-template.js +113 -0
- package/install/src/byan-v2/generation/templates/default-agent.md +49 -0
- package/install/src/byan-v2/generation/templates/test-template.md +1 -0
- package/install/src/byan-v2/index.js +199 -0
- package/install/src/byan-v2/observability/error-tracker.js +105 -0
- package/install/src/byan-v2/observability/logger.js +154 -0
- package/install/src/byan-v2/observability/metrics-collector.js +194 -0
- package/install/src/byan-v2/orchestrator/analysis-state.js +268 -0
- package/install/src/byan-v2/orchestrator/generation-state.js +340 -0
- package/install/src/byan-v2/orchestrator/interview-state.js +271 -0
- package/install/src/byan-v2/orchestrator/state-machine.js +204 -0
- package/install/src/core/cache/cache.js +126 -0
- package/install/src/core/context/context.js +86 -0
- package/install/src/core/dispatcher/dispatcher.js +135 -0
- package/install/src/core/worker-pool/worker-pool.js +194 -0
- package/install/src/core/workflow/workflow-executor.js +220 -0
- package/install/src/index.js +139 -0
- package/install/src/observability/dashboard/dashboard.js +191 -0
- package/install/src/observability/logger/structured-logger.js +254 -0
- package/install/src/observability/metrics/metrics-collector.js +325 -0
- package/install/switch-to-v2.sh +126 -0
- package/install/test-chalk-fix.sh +210 -0
- package/install/test-installer-v2.sh +204 -0
- package/install/test-path-resolution.sh +200 -0
- package/package.json +53 -33
- package/src/byan-v2/context/copilot-context.js +79 -0
- package/src/byan-v2/context/session-state.js +98 -0
- package/src/byan-v2/data/mantras.json +852 -0
- package/src/byan-v2/dispatcher/complexity-scorer.js +232 -0
- package/src/byan-v2/dispatcher/five-whys-analyzer.js +310 -0
- package/src/byan-v2/dispatcher/local-executor.js +221 -0
- package/src/byan-v2/dispatcher/task-router.js +122 -0
- package/src/byan-v2/dispatcher/task-tool-interface-mock.js +134 -0
- package/src/byan-v2/dispatcher/task-tool-interface.js +123 -0
- package/src/byan-v2/generation/agent-profile-validator.js +113 -0
- package/src/byan-v2/generation/mantra-validator.js +416 -0
- package/src/byan-v2/generation/profile-template.js +113 -0
- package/src/byan-v2/generation/templates/default-agent.md +49 -0
- package/src/byan-v2/generation/templates/test-template.md +1 -0
- package/src/byan-v2/index.js +652 -0
- package/src/byan-v2/integration/voice-integration.js +295 -0
- package/src/byan-v2/observability/error-tracker.js +105 -0
- package/src/byan-v2/observability/logger.js +154 -0
- package/src/byan-v2/observability/metrics-collector.js +194 -0
- package/src/byan-v2/orchestrator/active-listener.js +541 -0
- package/src/byan-v2/orchestrator/analysis-state.js +268 -0
- package/src/byan-v2/orchestrator/generation-state.js +340 -0
- package/src/byan-v2/orchestrator/glossary-builder.js +431 -0
- package/src/byan-v2/orchestrator/interview-state.js +353 -0
- package/src/byan-v2/orchestrator/state-machine.js +253 -0
- package/src/core/cache/cache.js +126 -0
- package/src/core/context/context.js +86 -0
- package/src/core/dispatcher/dispatcher.js +135 -0
- package/src/core/worker-pool/worker-pool.js +194 -0
- package/src/core/workflow/workflow-executor.js +220 -0
- package/src/index.js +139 -0
- package/src/observability/dashboard/dashboard.js +191 -0
- package/src/observability/logger/structured-logger.js +254 -0
- package/src/observability/metrics/metrics-collector.js +325 -0
- package/templates/.github/agents/bmad-agent-test-dynamic.md +0 -21
- package/templates/.github/agents/franck.md +0 -379
- /package/{CHANGELOG.md → install/CHANGELOG.md} +0 -0
- /package/{bin → install/bin}/create-byan-agent-backup.js +0 -0
- /package/{bin → install/bin}/create-byan-agent-fixed.js +0 -0
- /package/{bin → install/bin}/create-byan-agent-v2.js +0 -0
- /package/{bin → install/bin}/create-byan-agent.js +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmad-master.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-agent-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-module-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmb-workflow-builder.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-analyst.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-architect.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-dev.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-pm.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-quinn.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-sm.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-tech-writer.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-bmm-ux-designer.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-byan-test.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-byan.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-carmack.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-brainstorming-coach.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-creative-problem-solver.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-design-thinking-coach.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-innovation-strategist.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-presentation-master.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-cis-storyteller.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-marc.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-patnote.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-rachid.md +0 -0
- /package/{templates → install/templates}/.github/agents/bmad-agent-tea-tea.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/agent-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/byan-test.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/byan.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/marc.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/module-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/patnote.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/rachid.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/agents/workflow-builder.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/mantras.yaml +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/data/templates.yaml +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/delete-agent-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/edit-agent-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/interview-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/quick-create-workflow.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/templates/base-agent-template.md +0 -0
- /package/{templates → install/templates}/_bmad/bmb/workflows/byan/validate-agent-workflow.md +0 -0
- /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;
|