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,295 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { exec } = require('child_process');
|
|
4
|
+
const { promisify } = require('util');
|
|
5
|
+
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* VoiceIntegration - Turbo Whisper voice input integration for BYAN v2
|
|
10
|
+
*
|
|
11
|
+
* Enables voice-driven agent interaction through Turbo Whisper transcription.
|
|
12
|
+
* Supports GitHub Copilot CLI, Claude Code, and Codex platforms.
|
|
13
|
+
*
|
|
14
|
+
* @version 2.1.0
|
|
15
|
+
* @module integration/voice-integration
|
|
16
|
+
*/
|
|
17
|
+
class VoiceIntegration {
|
|
18
|
+
constructor(sessionState, logger) {
|
|
19
|
+
this.sessionState = sessionState;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
this.enabled = false;
|
|
22
|
+
this.config = null;
|
|
23
|
+
this.serverHealthy = false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Initialize voice integration
|
|
28
|
+
* Detects Turbo Whisper installation and configuration
|
|
29
|
+
* @returns {Promise<boolean>} True if initialization successful
|
|
30
|
+
*/
|
|
31
|
+
async initialize() {
|
|
32
|
+
try {
|
|
33
|
+
this.logger.debug('[VoiceIntegration] Initializing...');
|
|
34
|
+
|
|
35
|
+
const installed = await this.detectInstallation();
|
|
36
|
+
if (!installed) {
|
|
37
|
+
this.logger.info('[VoiceIntegration] Turbo Whisper not installed');
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const configLoaded = await this.loadConfig();
|
|
42
|
+
if (!configLoaded) {
|
|
43
|
+
this.logger.warn('[VoiceIntegration] Config not found, using defaults');
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const healthy = await this.checkHealth();
|
|
48
|
+
if (!healthy) {
|
|
49
|
+
this.logger.warn('[VoiceIntegration] Server not responding');
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.enabled = true;
|
|
54
|
+
this.logger.info('[VoiceIntegration] Initialized successfully');
|
|
55
|
+
this.sessionState.set('voice_integration_enabled', true);
|
|
56
|
+
|
|
57
|
+
return true;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
this.logger.error('[VoiceIntegration] Initialization failed:', error);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Detect if Turbo Whisper is installed
|
|
66
|
+
* @returns {Promise<boolean>}
|
|
67
|
+
*/
|
|
68
|
+
async detectInstallation() {
|
|
69
|
+
try {
|
|
70
|
+
const { stdout } = await execAsync('which turbo-whisper');
|
|
71
|
+
const turboWhisperPath = stdout.trim();
|
|
72
|
+
|
|
73
|
+
if (turboWhisperPath) {
|
|
74
|
+
this.logger.debug(`[VoiceIntegration] Found at: ${turboWhisperPath}`);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return false;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Load Turbo Whisper configuration
|
|
86
|
+
* @returns {Promise<boolean>}
|
|
87
|
+
*/
|
|
88
|
+
async loadConfig() {
|
|
89
|
+
try {
|
|
90
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
91
|
+
const configPath = path.join(homeDir, '.config', 'turbo-whisper', 'config.json');
|
|
92
|
+
|
|
93
|
+
if (!fs.existsSync(configPath)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
98
|
+
this.config = JSON.parse(configContent);
|
|
99
|
+
|
|
100
|
+
this.logger.debug('[VoiceIntegration] Config loaded:', {
|
|
101
|
+
api_url: this.config.api_url,
|
|
102
|
+
hotkey: this.config.hotkey,
|
|
103
|
+
claude_integration: this.config.claude_integration
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return true;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
this.logger.error('[VoiceIntegration] Config load failed:', error);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Check if Turbo Whisper server is healthy
|
|
115
|
+
* @returns {Promise<boolean>}
|
|
116
|
+
*/
|
|
117
|
+
async checkHealth() {
|
|
118
|
+
if (!this.config) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const apiUrl = this.config.api_url;
|
|
124
|
+
|
|
125
|
+
if (apiUrl.includes('localhost') || apiUrl.includes('127.0.0.1')) {
|
|
126
|
+
const port = apiUrl.match(/:(\d+)/)?.[1] || '8000';
|
|
127
|
+
const healthUrl = `http://localhost:${port}/health`;
|
|
128
|
+
|
|
129
|
+
const { stdout } = await execAsync(`curl -s ${healthUrl}`);
|
|
130
|
+
|
|
131
|
+
// fedirz/faster-whisper-server returns "OK" (string)
|
|
132
|
+
// Other servers may return {"status": "ok"} (object)
|
|
133
|
+
if (stdout.trim() === 'OK') {
|
|
134
|
+
this.serverHealthy = true;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const response = JSON.parse(stdout);
|
|
140
|
+
this.serverHealthy = response.status === 'ok';
|
|
141
|
+
return this.serverHealthy;
|
|
142
|
+
} catch {
|
|
143
|
+
// If not JSON and not "OK", server not ready
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
this.serverHealthy = true;
|
|
149
|
+
return true;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
this.logger.debug('[VoiceIntegration] Health check failed:', error.message);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get voice integration status
|
|
158
|
+
* @returns {Object} Status object
|
|
159
|
+
*/
|
|
160
|
+
getStatus() {
|
|
161
|
+
return {
|
|
162
|
+
enabled: this.enabled,
|
|
163
|
+
installed: this.config !== null,
|
|
164
|
+
serverHealthy: this.serverHealthy,
|
|
165
|
+
config: this.config ? {
|
|
166
|
+
apiUrl: this.config.api_url,
|
|
167
|
+
hotkey: this.config.hotkey?.join('+'),
|
|
168
|
+
claudeIntegration: this.config.claude_integration,
|
|
169
|
+
language: this.config.language
|
|
170
|
+
} : null
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Suggest voice input for long-form responses
|
|
176
|
+
* @param {string} context - Current interaction context
|
|
177
|
+
* @returns {string|null} Suggestion message or null
|
|
178
|
+
*/
|
|
179
|
+
suggestVoiceInput(context) {
|
|
180
|
+
if (!this.enabled) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const longFormContexts = [
|
|
185
|
+
'project_description',
|
|
186
|
+
'pain_points',
|
|
187
|
+
'requirements',
|
|
188
|
+
'use_cases',
|
|
189
|
+
'business_rules'
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
if (longFormContexts.some(ctx => context.includes(ctx))) {
|
|
193
|
+
const hotkey = this.config?.hotkey?.join('+') || 'Ctrl+Shift+Space';
|
|
194
|
+
return `💡 Voice input available: Press ${hotkey} to speak your response`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Guide user to install Turbo Whisper
|
|
202
|
+
* @returns {Object} Installation guidance
|
|
203
|
+
*/
|
|
204
|
+
getInstallationGuide() {
|
|
205
|
+
return {
|
|
206
|
+
message: 'Turbo Whisper not detected',
|
|
207
|
+
options: [
|
|
208
|
+
{
|
|
209
|
+
title: 'Install via BMAD Agent',
|
|
210
|
+
command: '@bmad-agent-turbo-whisper-integration',
|
|
211
|
+
description: 'Guided installation with wizard'
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
title: 'Manual Installation',
|
|
215
|
+
steps: [
|
|
216
|
+
'Ubuntu/Debian: sudo add-apt-repository ppa:bengweeks/turbo-whisper && sudo apt install turbo-whisper',
|
|
217
|
+
'Arch Linux: yay -S turbo-whisper',
|
|
218
|
+
'From source: git clone https://github.com/knowall-ai/turbo-whisper.git && cd turbo-whisper && pip install -e .'
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
title: 'Skip',
|
|
223
|
+
description: 'Continue without voice input'
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Validate voice transcription quality
|
|
231
|
+
* @param {string} transcription - Transcribed text
|
|
232
|
+
* @returns {Object} Quality metrics
|
|
233
|
+
*/
|
|
234
|
+
validateTranscription(transcription) {
|
|
235
|
+
const metrics = {
|
|
236
|
+
length: transcription.length,
|
|
237
|
+
wordCount: transcription.split(/\s+/).length,
|
|
238
|
+
hasSpecialChars: /[^\w\s]/g.test(transcription),
|
|
239
|
+
quality: 'unknown'
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
if (metrics.wordCount < 3) {
|
|
243
|
+
metrics.quality = 'poor';
|
|
244
|
+
metrics.warning = 'Transcription too short, may be incomplete';
|
|
245
|
+
} else if (metrics.wordCount < 10) {
|
|
246
|
+
metrics.quality = 'fair';
|
|
247
|
+
} else {
|
|
248
|
+
metrics.quality = 'good';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return metrics;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Offer voice input option during interview
|
|
256
|
+
* @param {string} questionId - Current question identifier
|
|
257
|
+
* @returns {string|null} Voice prompt suggestion
|
|
258
|
+
*/
|
|
259
|
+
offerVoicePrompt(questionId) {
|
|
260
|
+
if (!this.enabled) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const voiceOptimalQuestions = [
|
|
265
|
+
'project_description',
|
|
266
|
+
'pain_points',
|
|
267
|
+
'goals',
|
|
268
|
+
'requirements',
|
|
269
|
+
'use_cases',
|
|
270
|
+
'business_rules'
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
if (voiceOptimalQuestions.includes(questionId)) {
|
|
274
|
+
const hotkey = this.config?.hotkey?.join('+') || 'Ctrl+Shift+Space';
|
|
275
|
+
return `[Voice: ${hotkey}] You can speak your response for faster input`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Log voice usage metrics
|
|
283
|
+
* @param {Object} metrics - Usage metrics
|
|
284
|
+
*/
|
|
285
|
+
logUsageMetrics(metrics) {
|
|
286
|
+
const usage = this.sessionState.get('voice_usage_metrics') || [];
|
|
287
|
+
usage.push({
|
|
288
|
+
timestamp: new Date().toISOString(),
|
|
289
|
+
...metrics
|
|
290
|
+
});
|
|
291
|
+
this.sessionState.set('voice_usage_metrics', usage);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
module.exports = VoiceIntegration;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ErrorTracker - Track and store errors with context
|
|
3
|
+
*
|
|
4
|
+
* Error Types:
|
|
5
|
+
* - ROUTING_ERROR: Errors during task routing
|
|
6
|
+
* - EXECUTION_ERROR: Errors during task execution
|
|
7
|
+
* - VALIDATION_ERROR: Errors during validation
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Store up to maxErrors (default 100) in FIFO order
|
|
11
|
+
* - Track error type, message, stack, context, timestamp
|
|
12
|
+
* - Filter errors by type
|
|
13
|
+
* - Get error statistics
|
|
14
|
+
*
|
|
15
|
+
* Methods:
|
|
16
|
+
* - trackError(errorData)
|
|
17
|
+
* - getErrors()
|
|
18
|
+
* - getErrorsByType(type)
|
|
19
|
+
* - getErrorStats()
|
|
20
|
+
* - clearErrors()
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
class ErrorTracker {
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.maxErrors = options.maxErrors || 100;
|
|
26
|
+
this.errors = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Track an error with full context
|
|
31
|
+
* @param {Object} errorData - Error data with type, message, error, context
|
|
32
|
+
*/
|
|
33
|
+
trackError(errorData) {
|
|
34
|
+
if (!errorData) return;
|
|
35
|
+
|
|
36
|
+
const { type, message, error, context } = errorData;
|
|
37
|
+
|
|
38
|
+
// Build error entry
|
|
39
|
+
const errorEntry = {
|
|
40
|
+
type,
|
|
41
|
+
message: message || error?.message,
|
|
42
|
+
stack: error?.stack,
|
|
43
|
+
context,
|
|
44
|
+
timestamp: new Date().toISOString()
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Add to errors array
|
|
48
|
+
this.errors.push(errorEntry);
|
|
49
|
+
|
|
50
|
+
// Enforce max size (FIFO)
|
|
51
|
+
if (this.errors.length > this.maxErrors) {
|
|
52
|
+
this.errors.shift(); // Remove oldest
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get all tracked errors
|
|
58
|
+
* @returns {Array} Array of error objects
|
|
59
|
+
*/
|
|
60
|
+
getErrors() {
|
|
61
|
+
// Return copy to prevent external modification
|
|
62
|
+
return [...this.errors];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get errors filtered by type
|
|
67
|
+
* @param {string} type - Error type to filter by
|
|
68
|
+
* @returns {Array} Array of errors matching type
|
|
69
|
+
*/
|
|
70
|
+
getErrorsByType(type) {
|
|
71
|
+
return this.errors.filter(error => error.type === type);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get error statistics
|
|
76
|
+
* @returns {Object} Statistics with total and breakdown by type
|
|
77
|
+
*/
|
|
78
|
+
getErrorStats() {
|
|
79
|
+
const stats = {
|
|
80
|
+
total: this.errors.length,
|
|
81
|
+
byType: {
|
|
82
|
+
ROUTING_ERROR: 0,
|
|
83
|
+
EXECUTION_ERROR: 0,
|
|
84
|
+
VALIDATION_ERROR: 0
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
this.errors.forEach(error => {
|
|
89
|
+
if (stats.byType[error.type] !== undefined) {
|
|
90
|
+
stats.byType[error.type]++;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return stats;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Clear all tracked errors
|
|
99
|
+
*/
|
|
100
|
+
clearErrors() {
|
|
101
|
+
this.errors = [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = ErrorTracker;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger - Winston-based structured logging
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - JSON format logging
|
|
6
|
+
* - File + Console output
|
|
7
|
+
* - Methods: logTaskRouting(), logTaskExecution(), logError()
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const winston = require('winston');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
class Logger {
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
const {
|
|
17
|
+
logDir = path.join(process.cwd(), 'logs'),
|
|
18
|
+
logFile = 'byan.log',
|
|
19
|
+
consoleOutput = true,
|
|
20
|
+
level = 'info'
|
|
21
|
+
} = options;
|
|
22
|
+
|
|
23
|
+
this.logDir = logDir;
|
|
24
|
+
this.logFile = logFile;
|
|
25
|
+
this.logPath = path.join(logDir, logFile);
|
|
26
|
+
|
|
27
|
+
// Ensure log directory exists
|
|
28
|
+
if (!fs.existsSync(logDir)) {
|
|
29
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Configure transports
|
|
33
|
+
const transports = [
|
|
34
|
+
new winston.transports.File({
|
|
35
|
+
filename: this.logPath,
|
|
36
|
+
format: winston.format.json()
|
|
37
|
+
})
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
if (consoleOutput) {
|
|
41
|
+
transports.push(
|
|
42
|
+
new winston.transports.Console({
|
|
43
|
+
format: winston.format.combine(
|
|
44
|
+
winston.format.colorize(),
|
|
45
|
+
winston.format.simple()
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Create Winston logger
|
|
52
|
+
this.logger = winston.createLogger({
|
|
53
|
+
level,
|
|
54
|
+
format: winston.format.combine(
|
|
55
|
+
winston.format.timestamp(),
|
|
56
|
+
winston.format.json()
|
|
57
|
+
),
|
|
58
|
+
transports
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Log task routing decision
|
|
64
|
+
* @param {Object} routingData - Routing decision data
|
|
65
|
+
*/
|
|
66
|
+
logTaskRouting(routingData) {
|
|
67
|
+
if (!routingData) return;
|
|
68
|
+
|
|
69
|
+
const { task, executor, complexity, canFallback, reasoning } = routingData;
|
|
70
|
+
|
|
71
|
+
this.logger.info('Task routing decision', {
|
|
72
|
+
taskType: task?.type,
|
|
73
|
+
prompt: task?.prompt,
|
|
74
|
+
metadata: task?.metadata,
|
|
75
|
+
executor,
|
|
76
|
+
complexity,
|
|
77
|
+
canFallback,
|
|
78
|
+
reasoning
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Log task execution result
|
|
84
|
+
* @param {Object} executionData - Execution result data
|
|
85
|
+
*/
|
|
86
|
+
logTaskExecution(executionData) {
|
|
87
|
+
if (!executionData) return;
|
|
88
|
+
|
|
89
|
+
const { task, executor, duration, success, result, error, tokens } = executionData;
|
|
90
|
+
|
|
91
|
+
this.logger.info('Task execution completed', {
|
|
92
|
+
taskType: task?.type,
|
|
93
|
+
prompt: task?.prompt,
|
|
94
|
+
executor,
|
|
95
|
+
duration,
|
|
96
|
+
success,
|
|
97
|
+
result,
|
|
98
|
+
error,
|
|
99
|
+
tokens
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Log error with context
|
|
105
|
+
* @param {Object} errorData - Error data with type, message, error, context
|
|
106
|
+
*/
|
|
107
|
+
logError(errorData) {
|
|
108
|
+
if (!errorData) return;
|
|
109
|
+
|
|
110
|
+
const { type, message, error, context } = errorData;
|
|
111
|
+
|
|
112
|
+
this.logger.error(message || 'Error occurred', {
|
|
113
|
+
errorType: type,
|
|
114
|
+
stack: error?.stack,
|
|
115
|
+
context
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Generic info log
|
|
121
|
+
* @param {string} message - Log message
|
|
122
|
+
* @param {Object} data - Additional data
|
|
123
|
+
*/
|
|
124
|
+
info(message, data = {}) {
|
|
125
|
+
this.logger.info(message, data);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Generic warn log
|
|
130
|
+
* @param {string} message - Log message
|
|
131
|
+
* @param {Object} data - Additional data
|
|
132
|
+
*/
|
|
133
|
+
warn(message, data = {}) {
|
|
134
|
+
this.logger.warn(message, data);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Generic error log
|
|
139
|
+
* @param {string} message - Log message
|
|
140
|
+
* @param {Object} data - Additional data
|
|
141
|
+
*/
|
|
142
|
+
error(message, data = {}) {
|
|
143
|
+
this.logger.error(message, data);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Close logger and flush transports
|
|
148
|
+
*/
|
|
149
|
+
close() {
|
|
150
|
+
this.logger.close();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = Logger;
|