claude-voice 1.0.0
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/LICENSE +21 -0
- package/README.md +395 -0
- package/bin/claude-voice +29 -0
- package/config/default.json +109 -0
- package/config/voice-prompt.md +27 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1103 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +140 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +179 -0
- package/dist/config.js.map +1 -0
- package/dist/env.d.ts +40 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +175 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +140 -0
- package/dist/index.js.map +1 -0
- package/dist/platform/index.d.ts +35 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +170 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +185 -0
- package/dist/server.js.map +1 -0
- package/dist/stt/index.d.ts +15 -0
- package/dist/stt/index.d.ts.map +1 -0
- package/dist/stt/index.js +54 -0
- package/dist/stt/index.js.map +1 -0
- package/dist/stt/providers/openai.d.ts +15 -0
- package/dist/stt/providers/openai.d.ts.map +1 -0
- package/dist/stt/providers/openai.js +74 -0
- package/dist/stt/providers/openai.js.map +1 -0
- package/dist/stt/providers/sherpa-onnx.d.ts +50 -0
- package/dist/stt/providers/sherpa-onnx.d.ts.map +1 -0
- package/dist/stt/providers/sherpa-onnx.js +237 -0
- package/dist/stt/providers/sherpa-onnx.js.map +1 -0
- package/dist/stt/providers/whisper-local.d.ts +19 -0
- package/dist/stt/providers/whisper-local.d.ts.map +1 -0
- package/dist/stt/providers/whisper-local.js +141 -0
- package/dist/stt/providers/whisper-local.js.map +1 -0
- package/dist/terminal/input-injector.d.ts +55 -0
- package/dist/terminal/input-injector.d.ts.map +1 -0
- package/dist/terminal/input-injector.js +189 -0
- package/dist/terminal/input-injector.js.map +1 -0
- package/dist/tts/index.d.ts +20 -0
- package/dist/tts/index.d.ts.map +1 -0
- package/dist/tts/index.js +72 -0
- package/dist/tts/index.js.map +1 -0
- package/dist/tts/providers/elevenlabs.d.ts +23 -0
- package/dist/tts/providers/elevenlabs.d.ts.map +1 -0
- package/dist/tts/providers/elevenlabs.js +142 -0
- package/dist/tts/providers/elevenlabs.js.map +1 -0
- package/dist/tts/providers/macos-say.d.ts +17 -0
- package/dist/tts/providers/macos-say.d.ts.map +1 -0
- package/dist/tts/providers/macos-say.js +72 -0
- package/dist/tts/providers/macos-say.js.map +1 -0
- package/dist/tts/providers/openai.d.ts +19 -0
- package/dist/tts/providers/openai.d.ts.map +1 -0
- package/dist/tts/providers/openai.js +118 -0
- package/dist/tts/providers/openai.js.map +1 -0
- package/dist/tts/providers/piper.d.ts +48 -0
- package/dist/tts/providers/piper.d.ts.map +1 -0
- package/dist/tts/providers/piper.js +417 -0
- package/dist/tts/providers/piper.js.map +1 -0
- package/dist/voice-input.d.ts +9 -0
- package/dist/voice-input.d.ts.map +1 -0
- package/dist/voice-input.js +137 -0
- package/dist/voice-input.js.map +1 -0
- package/dist/wake-word/index.d.ts +19 -0
- package/dist/wake-word/index.d.ts.map +1 -0
- package/dist/wake-word/index.js +200 -0
- package/dist/wake-word/index.js.map +1 -0
- package/dist/wake-word/recorder.d.ts +19 -0
- package/dist/wake-word/recorder.d.ts.map +1 -0
- package/dist/wake-word/recorder.js +145 -0
- package/dist/wake-word/recorder.js.map +1 -0
- package/hooks/notification.js +125 -0
- package/hooks/post-tool-use.js +374 -0
- package/hooks/session-start.js +212 -0
- package/hooks/stop.js +254 -0
- package/models/.gitkeep +0 -0
- package/package.json +80 -0
- package/python/stt_service.py +59 -0
- package/python/voice_input.py +154 -0
- package/scripts/install.sh +147 -0
- package/scripts/listen.py +161 -0
- package/scripts/postinstall.js +57 -0
- package/scripts/record.sh +79 -0
- package/scripts/setup-hooks.sh +22 -0
- package/scripts/voice-input.sh +66 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAeH,iBAAe,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB1C;AA6ED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Claude Voice Extension
|
|
5
|
+
*
|
|
6
|
+
* Main entry point for the voice extension daemon.
|
|
7
|
+
* Provides TTS/STT services and wake word detection for Claude Code.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.startDaemon = startDaemon;
|
|
44
|
+
const config_1 = require("./config");
|
|
45
|
+
const env_1 = require("./env");
|
|
46
|
+
const server_1 = require("./server");
|
|
47
|
+
const wake_word_1 = require("./wake-word");
|
|
48
|
+
const stt_1 = require("./stt");
|
|
49
|
+
const input_injector_1 = require("./terminal/input-injector");
|
|
50
|
+
const recorder_1 = require("./wake-word/recorder");
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const os = __importStar(require("os"));
|
|
53
|
+
let wakeWordDetector = null;
|
|
54
|
+
let sttManager = null;
|
|
55
|
+
async function startDaemon() {
|
|
56
|
+
// Load API keys from ~/.claude-voice/.env first
|
|
57
|
+
(0, env_1.loadEnvVars)();
|
|
58
|
+
const config = (0, config_1.loadConfig)();
|
|
59
|
+
console.log('Starting Claude Voice Extension daemon...');
|
|
60
|
+
// Start the HTTP API server
|
|
61
|
+
await (0, server_1.startServer)();
|
|
62
|
+
// Initialize STT manager for voice commands
|
|
63
|
+
sttManager = new stt_1.STTManager(config.stt);
|
|
64
|
+
// Initialize wake word detection if enabled
|
|
65
|
+
if (config.wakeWord.enabled) {
|
|
66
|
+
await initializeWakeWord(config);
|
|
67
|
+
}
|
|
68
|
+
console.log('Claude Voice Extension is ready!');
|
|
69
|
+
console.log(`TTS Provider: ${config.tts.provider}`);
|
|
70
|
+
console.log(`STT Provider: ${config.stt.provider}`);
|
|
71
|
+
console.log(`Wake Word: ${config.wakeWord.enabled ? 'enabled' : 'disabled'}`);
|
|
72
|
+
}
|
|
73
|
+
async function initializeWakeWord(config) {
|
|
74
|
+
try {
|
|
75
|
+
wakeWordDetector = new wake_word_1.WakeWordDetector(config.wakeWord, config.recording);
|
|
76
|
+
wakeWordDetector.on('wakeword', () => {
|
|
77
|
+
console.log('Wake word detected! Listening for command...');
|
|
78
|
+
});
|
|
79
|
+
wakeWordDetector.on('listening', () => {
|
|
80
|
+
// Play a sound or provide feedback that we're listening
|
|
81
|
+
if (config.debug) {
|
|
82
|
+
console.log('Recording command...');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
wakeWordDetector.on('command', async (audioBuffer) => {
|
|
86
|
+
try {
|
|
87
|
+
// Save audio to temp file
|
|
88
|
+
const tempPath = path.join(os.tmpdir(), `voice-command-${Date.now()}.wav`);
|
|
89
|
+
await (0, recorder_1.saveToWav)(audioBuffer, tempPath, config.recording.sampleRate, config.recording.channels);
|
|
90
|
+
// Transcribe
|
|
91
|
+
if (sttManager) {
|
|
92
|
+
const transcript = await sttManager.transcribe(tempPath);
|
|
93
|
+
if (transcript && transcript.trim()) {
|
|
94
|
+
console.log(`Transcribed: "${transcript}"`);
|
|
95
|
+
// Send to Claude Code
|
|
96
|
+
await (0, input_injector_1.sendToClaudeCode)(transcript);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Cleanup
|
|
100
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
101
|
+
fs.unlinkSync(tempPath);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Error processing voice command:', error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
wakeWordDetector.on('error', (error) => {
|
|
108
|
+
console.error('Wake word detector error:', error);
|
|
109
|
+
});
|
|
110
|
+
await wakeWordDetector.initialize();
|
|
111
|
+
await wakeWordDetector.start();
|
|
112
|
+
console.log('Wake word detection active. Say "Jarvis" to start speaking.');
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.warn('Failed to initialize wake word detection:', error);
|
|
116
|
+
console.warn('Voice input will be disabled. Set PICOVOICE_ACCESS_KEY to enable.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Handle graceful shutdown
|
|
120
|
+
process.on('SIGINT', async () => {
|
|
121
|
+
console.log('\nShutting down...');
|
|
122
|
+
if (wakeWordDetector) {
|
|
123
|
+
wakeWordDetector.cleanup();
|
|
124
|
+
}
|
|
125
|
+
process.exit(0);
|
|
126
|
+
});
|
|
127
|
+
process.on('SIGTERM', async () => {
|
|
128
|
+
if (wakeWordDetector) {
|
|
129
|
+
wakeWordDetector.cleanup();
|
|
130
|
+
}
|
|
131
|
+
process.exit(0);
|
|
132
|
+
});
|
|
133
|
+
// Run if called directly
|
|
134
|
+
if (require.main === module) {
|
|
135
|
+
startDaemon().catch((error) => {
|
|
136
|
+
console.error('Failed to start daemon:', error);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type Platform = 'darwin' | 'linux' | 'unsupported';
|
|
2
|
+
export interface PlatformCapabilities {
|
|
3
|
+
platform: Platform;
|
|
4
|
+
nativeTTS: boolean;
|
|
5
|
+
nativeTTSCommand: string;
|
|
6
|
+
audioPlayer: string;
|
|
7
|
+
terminalInjection: 'applescript' | 'xdotool' | 'ydotool' | 'none';
|
|
8
|
+
defaultTerminal: string;
|
|
9
|
+
supportsWakeWord: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the current platform
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPlatform(): Platform;
|
|
15
|
+
/**
|
|
16
|
+
* Check if a command is available in PATH
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasCommand(cmd: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Get platform-specific capabilities
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPlatformCapabilities(): PlatformCapabilities;
|
|
23
|
+
/**
|
|
24
|
+
* Get platform-specific installation instructions
|
|
25
|
+
*/
|
|
26
|
+
export declare function getInstallInstructions(): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Check if the platform is supported
|
|
29
|
+
*/
|
|
30
|
+
export declare function isPlatformSupported(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get a summary of platform status
|
|
33
|
+
*/
|
|
34
|
+
export declare function getPlatformSummary(): string;
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,aAAa,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAClE,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAKtC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAsD9D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CA4BjD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAW3C"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getPlatform = getPlatform;
|
|
37
|
+
exports.hasCommand = hasCommand;
|
|
38
|
+
exports.getPlatformCapabilities = getPlatformCapabilities;
|
|
39
|
+
exports.getInstallInstructions = getInstallInstructions;
|
|
40
|
+
exports.isPlatformSupported = isPlatformSupported;
|
|
41
|
+
exports.getPlatformSummary = getPlatformSummary;
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
/**
|
|
45
|
+
* Get the current platform
|
|
46
|
+
*/
|
|
47
|
+
function getPlatform() {
|
|
48
|
+
const platform = os.platform();
|
|
49
|
+
if (platform === 'darwin')
|
|
50
|
+
return 'darwin';
|
|
51
|
+
if (platform === 'linux')
|
|
52
|
+
return 'linux';
|
|
53
|
+
return 'unsupported';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a command is available in PATH
|
|
57
|
+
*/
|
|
58
|
+
function hasCommand(cmd) {
|
|
59
|
+
try {
|
|
60
|
+
(0, child_process_1.execSync)(`which ${cmd}`, { stdio: 'ignore' });
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get platform-specific capabilities
|
|
69
|
+
*/
|
|
70
|
+
function getPlatformCapabilities() {
|
|
71
|
+
const platform = getPlatform();
|
|
72
|
+
if (platform === 'darwin') {
|
|
73
|
+
return {
|
|
74
|
+
platform: 'darwin',
|
|
75
|
+
nativeTTS: true,
|
|
76
|
+
nativeTTSCommand: 'say',
|
|
77
|
+
audioPlayer: 'afplay',
|
|
78
|
+
terminalInjection: 'applescript',
|
|
79
|
+
defaultTerminal: process.env.TERM_PROGRAM === 'iTerm.app' ? 'iTerm' : 'Terminal',
|
|
80
|
+
supportsWakeWord: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (platform === 'linux') {
|
|
84
|
+
// Determine terminal injection method
|
|
85
|
+
let terminalInjection = 'none';
|
|
86
|
+
if (hasCommand('xdotool')) {
|
|
87
|
+
terminalInjection = 'xdotool';
|
|
88
|
+
}
|
|
89
|
+
else if (hasCommand('ydotool')) {
|
|
90
|
+
terminalInjection = 'ydotool';
|
|
91
|
+
}
|
|
92
|
+
// Determine audio player
|
|
93
|
+
let audioPlayer = '';
|
|
94
|
+
if (hasCommand('ffplay')) {
|
|
95
|
+
audioPlayer = 'ffplay';
|
|
96
|
+
}
|
|
97
|
+
else if (hasCommand('aplay')) {
|
|
98
|
+
audioPlayer = 'aplay';
|
|
99
|
+
}
|
|
100
|
+
else if (hasCommand('paplay')) {
|
|
101
|
+
audioPlayer = 'paplay';
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
platform: 'linux',
|
|
105
|
+
nativeTTS: hasCommand('espeak') || hasCommand('espeak-ng'),
|
|
106
|
+
nativeTTSCommand: hasCommand('espeak-ng') ? 'espeak-ng' : 'espeak',
|
|
107
|
+
audioPlayer,
|
|
108
|
+
terminalInjection,
|
|
109
|
+
defaultTerminal: process.env.TERM_PROGRAM || 'gnome-terminal',
|
|
110
|
+
supportsWakeWord: true,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
platform: 'unsupported',
|
|
115
|
+
nativeTTS: false,
|
|
116
|
+
nativeTTSCommand: '',
|
|
117
|
+
audioPlayer: '',
|
|
118
|
+
terminalInjection: 'none',
|
|
119
|
+
defaultTerminal: '',
|
|
120
|
+
supportsWakeWord: false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get platform-specific installation instructions
|
|
125
|
+
*/
|
|
126
|
+
function getInstallInstructions() {
|
|
127
|
+
const platform = getPlatform();
|
|
128
|
+
const caps = getPlatformCapabilities();
|
|
129
|
+
const instructions = [];
|
|
130
|
+
if (platform === 'darwin') {
|
|
131
|
+
if (!caps.nativeTTS) {
|
|
132
|
+
instructions.push('macOS should have native TTS - check system settings');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (platform === 'linux') {
|
|
136
|
+
if (!caps.nativeTTS) {
|
|
137
|
+
instructions.push('Install espeak for TTS: sudo apt install espeak');
|
|
138
|
+
}
|
|
139
|
+
if (caps.terminalInjection === 'none') {
|
|
140
|
+
instructions.push('Install xdotool for terminal injection: sudo apt install xdotool');
|
|
141
|
+
}
|
|
142
|
+
if (!caps.audioPlayer) {
|
|
143
|
+
instructions.push('Install ffmpeg for audio playback: sudo apt install ffmpeg');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (platform === 'unsupported') {
|
|
147
|
+
instructions.push('This platform is not fully supported. Some features may not work.');
|
|
148
|
+
}
|
|
149
|
+
return instructions;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if the platform is supported
|
|
153
|
+
*/
|
|
154
|
+
function isPlatformSupported() {
|
|
155
|
+
return getPlatform() !== 'unsupported';
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get a summary of platform status
|
|
159
|
+
*/
|
|
160
|
+
function getPlatformSummary() {
|
|
161
|
+
const caps = getPlatformCapabilities();
|
|
162
|
+
const lines = [];
|
|
163
|
+
lines.push(`Platform: ${caps.platform}`);
|
|
164
|
+
lines.push(`Native TTS: ${caps.nativeTTS ? caps.nativeTTSCommand : 'not available'}`);
|
|
165
|
+
lines.push(`Audio Player: ${caps.audioPlayer || 'not available'}`);
|
|
166
|
+
lines.push(`Terminal Injection: ${caps.terminalInjection}`);
|
|
167
|
+
lines.push(`Wake Word Support: ${caps.supportsWakeWord ? 'yes' : 'no'}`);
|
|
168
|
+
return lines.join('\n');
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,GAAG,6CAAY,CAAC;AAOtB,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAuID,wBAAgB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAW3C;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.app = void 0;
|
|
40
|
+
exports.initializeManagers = initializeManagers;
|
|
41
|
+
exports.startServer = startServer;
|
|
42
|
+
const express_1 = __importDefault(require("express"));
|
|
43
|
+
const config_1 = require("./config");
|
|
44
|
+
const tts_1 = require("./tts");
|
|
45
|
+
const stt_1 = require("./stt");
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const os = __importStar(require("os"));
|
|
49
|
+
const app = (0, express_1.default)();
|
|
50
|
+
exports.app = app;
|
|
51
|
+
app.use(express_1.default.json());
|
|
52
|
+
app.use(express_1.default.raw({ type: 'audio/*', limit: '50mb' }));
|
|
53
|
+
let ttsManager;
|
|
54
|
+
let sttManager;
|
|
55
|
+
function initializeManagers() {
|
|
56
|
+
const config = (0, config_1.loadConfig)();
|
|
57
|
+
ttsManager = new tts_1.TTSManager(config.tts);
|
|
58
|
+
sttManager = new stt_1.STTManager(config.stt);
|
|
59
|
+
}
|
|
60
|
+
// Health check
|
|
61
|
+
app.get('/status', (_req, res) => {
|
|
62
|
+
const config = (0, config_1.loadConfig)();
|
|
63
|
+
res.json({
|
|
64
|
+
status: 'running',
|
|
65
|
+
tts: {
|
|
66
|
+
provider: config.tts.provider,
|
|
67
|
+
ready: ttsManager?.isReady() ?? false,
|
|
68
|
+
},
|
|
69
|
+
stt: {
|
|
70
|
+
provider: config.stt.provider,
|
|
71
|
+
ready: sttManager?.isReady() ?? false,
|
|
72
|
+
},
|
|
73
|
+
wakeWord: {
|
|
74
|
+
enabled: config.wakeWord.enabled,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
// Text-to-Speech endpoint
|
|
79
|
+
app.post('/tts', async (req, res, next) => {
|
|
80
|
+
try {
|
|
81
|
+
const { text, priority } = req.body;
|
|
82
|
+
if (!text || typeof text !== 'string') {
|
|
83
|
+
res.status(400).json({ error: 'Missing or invalid "text" field' });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
await ttsManager.speak(text, priority === 'high');
|
|
87
|
+
res.json({ success: true, message: 'Speech queued' });
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
next(error);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// Speech-to-Text endpoint (accepts audio file)
|
|
94
|
+
app.post('/stt', async (req, res, next) => {
|
|
95
|
+
try {
|
|
96
|
+
let audioPath;
|
|
97
|
+
let shouldCleanup = false;
|
|
98
|
+
// Handle raw audio data
|
|
99
|
+
if (Buffer.isBuffer(req.body)) {
|
|
100
|
+
const tempDir = os.tmpdir();
|
|
101
|
+
audioPath = path.join(tempDir, `stt-${Date.now()}.wav`);
|
|
102
|
+
fs.writeFileSync(audioPath, req.body);
|
|
103
|
+
shouldCleanup = true;
|
|
104
|
+
}
|
|
105
|
+
else if (req.body.audioPath) {
|
|
106
|
+
// Handle file path
|
|
107
|
+
audioPath = req.body.audioPath;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
res.status(400).json({ error: 'Missing audio data or audioPath' });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const transcript = await sttManager.transcribe(audioPath);
|
|
114
|
+
if (shouldCleanup) {
|
|
115
|
+
fs.unlinkSync(audioPath);
|
|
116
|
+
}
|
|
117
|
+
res.json({ success: true, transcript });
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
next(error);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
// Stop current playback
|
|
124
|
+
app.post('/tts/stop', (_req, res) => {
|
|
125
|
+
ttsManager.stop();
|
|
126
|
+
res.json({ success: true, message: 'Playback stopped' });
|
|
127
|
+
});
|
|
128
|
+
// Get current configuration
|
|
129
|
+
app.get('/config', (_req, res) => {
|
|
130
|
+
const config = (0, config_1.loadConfig)();
|
|
131
|
+
// Remove sensitive data
|
|
132
|
+
const safeConfig = { ...config };
|
|
133
|
+
res.json(safeConfig);
|
|
134
|
+
});
|
|
135
|
+
// Update configuration
|
|
136
|
+
app.post('/config', (req, res) => {
|
|
137
|
+
try {
|
|
138
|
+
const updates = req.body;
|
|
139
|
+
(0, config_1.saveConfig)(updates);
|
|
140
|
+
// Reinitialize managers with new config
|
|
141
|
+
initializeManagers();
|
|
142
|
+
res.json({ success: true, message: 'Configuration updated' });
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
res.status(500).json({ error: 'Failed to update configuration' });
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
// Set TTS provider
|
|
149
|
+
app.post('/tts/provider', (req, res) => {
|
|
150
|
+
const { provider } = req.body;
|
|
151
|
+
if (!['macos-say', 'openai', 'elevenlabs'].includes(provider)) {
|
|
152
|
+
res.status(400).json({ error: 'Invalid provider' });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
(0, config_1.saveConfig)({ tts: { ...(0, config_1.loadConfig)().tts, provider } });
|
|
156
|
+
initializeManagers();
|
|
157
|
+
res.json({ success: true, provider });
|
|
158
|
+
});
|
|
159
|
+
// Set STT provider
|
|
160
|
+
app.post('/stt/provider', (req, res) => {
|
|
161
|
+
const { provider } = req.body;
|
|
162
|
+
if (!['whisper-local', 'openai'].includes(provider)) {
|
|
163
|
+
res.status(400).json({ error: 'Invalid provider' });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
(0, config_1.saveConfig)({ stt: { ...(0, config_1.loadConfig)().stt, provider } });
|
|
167
|
+
initializeManagers();
|
|
168
|
+
res.json({ success: true, provider });
|
|
169
|
+
});
|
|
170
|
+
// Error handling middleware
|
|
171
|
+
app.use((err, _req, res, _next) => {
|
|
172
|
+
console.error('Server error:', err);
|
|
173
|
+
res.status(500).json({ error: err.message || 'Internal server error' });
|
|
174
|
+
});
|
|
175
|
+
function startServer() {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
const config = (0, config_1.loadConfig)();
|
|
178
|
+
initializeManagers();
|
|
179
|
+
app.listen(config.server.port, config.server.host, () => {
|
|
180
|
+
console.log(`Claude Voice Extension server running at http://${config.server.host}:${config.server.port}`);
|
|
181
|
+
resolve();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { STTConfig } from '../config';
|
|
2
|
+
export interface STTProvider {
|
|
3
|
+
name: string;
|
|
4
|
+
transcribe(audioPath: string): Promise<string>;
|
|
5
|
+
isReady(): boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class STTManager {
|
|
8
|
+
private provider;
|
|
9
|
+
constructor(config: STTConfig);
|
|
10
|
+
private createProvider;
|
|
11
|
+
transcribe(audioPath: string): Promise<string>;
|
|
12
|
+
isReady(): boolean;
|
|
13
|
+
getProviderName(): string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stt/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAKtC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAc;gBAElB,MAAM,EAAE,SAAS;IAI7B,OAAO,CAAC,cAAc;IAgChB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpD,OAAO,IAAI,OAAO;IAIlB,eAAe,IAAI,MAAM;CAG1B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STTManager = void 0;
|
|
4
|
+
const whisper_local_1 = require("./providers/whisper-local");
|
|
5
|
+
const openai_1 = require("./providers/openai");
|
|
6
|
+
const sherpa_onnx_1 = require("./providers/sherpa-onnx");
|
|
7
|
+
class STTManager {
|
|
8
|
+
provider;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.provider = this.createProvider(config);
|
|
11
|
+
}
|
|
12
|
+
createProvider(config) {
|
|
13
|
+
switch (config.provider) {
|
|
14
|
+
case 'sherpa-onnx':
|
|
15
|
+
return new sherpa_onnx_1.SherpaOnnxProvider({
|
|
16
|
+
model: config.sherpaOnnx?.model || 'whisper-tiny',
|
|
17
|
+
language: config.language,
|
|
18
|
+
});
|
|
19
|
+
case 'whisper-local':
|
|
20
|
+
return new whisper_local_1.WhisperLocalProvider({
|
|
21
|
+
...config.whisperLocal,
|
|
22
|
+
language: config.language,
|
|
23
|
+
});
|
|
24
|
+
case 'openai':
|
|
25
|
+
return new openai_1.OpenAISTTProvider(config.openai);
|
|
26
|
+
case 'disabled':
|
|
27
|
+
// Return a dummy provider that always fails
|
|
28
|
+
return {
|
|
29
|
+
name: 'disabled',
|
|
30
|
+
transcribe: async () => {
|
|
31
|
+
throw new Error('STT is disabled');
|
|
32
|
+
},
|
|
33
|
+
isReady: () => false,
|
|
34
|
+
};
|
|
35
|
+
default:
|
|
36
|
+
console.warn(`Unknown STT provider: ${config.provider}, falling back to whisper-local`);
|
|
37
|
+
return new whisper_local_1.WhisperLocalProvider({
|
|
38
|
+
...config.whisperLocal,
|
|
39
|
+
language: config.language,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async transcribe(audioPath) {
|
|
44
|
+
return this.provider.transcribe(audioPath);
|
|
45
|
+
}
|
|
46
|
+
isReady() {
|
|
47
|
+
return this.provider.isReady();
|
|
48
|
+
}
|
|
49
|
+
getProviderName() {
|
|
50
|
+
return this.provider.name;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.STTManager = STTManager;
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stt/index.ts"],"names":[],"mappings":";;;AACA,6DAAiE;AACjE,+CAAuD;AACvD,yDAA6D;AAQ7D,MAAa,UAAU;IACb,QAAQ,CAAc;IAE9B,YAAY,MAAiB;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAEO,cAAc,CAAC,MAAiB;QACtC,QAAQ,MAAM,CAAC,QAAQ,EAAE,CAAC;YACxB,KAAK,aAAa;gBAChB,OAAO,IAAI,gCAAkB,CAAC;oBAC5B,KAAK,EAAG,MAAc,CAAC,UAAU,EAAE,KAAK,IAAI,cAAc;oBAC1D,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC;YACL,KAAK,eAAe;gBAClB,OAAO,IAAI,oCAAoB,CAAC;oBAC9B,GAAG,MAAM,CAAC,YAAY;oBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC;YACL,KAAK,QAAQ;gBACX,OAAO,IAAI,0BAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC9C,KAAK,UAAU;gBACb,4CAA4C;gBAC5C,OAAO;oBACL,IAAI,EAAE,UAAU;oBAChB,UAAU,EAAE,KAAK,IAAI,EAAE;wBACrB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;oBACrC,CAAC;oBACD,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;iBACrB,CAAC;YACJ;gBACE,OAAO,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,QAAQ,iCAAiC,CAAC,CAAC;gBACxF,OAAO,IAAI,oCAAoB,CAAC;oBAC9B,GAAG,MAAM,CAAC,YAAY;oBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF;AAlDD,gCAkDC"}
|