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,15 @@
|
|
|
1
|
+
import { STTProvider } from '../index';
|
|
2
|
+
interface OpenAISTTConfig {
|
|
3
|
+
model: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class OpenAISTTProvider implements STTProvider {
|
|
6
|
+
name: string;
|
|
7
|
+
private config;
|
|
8
|
+
private client;
|
|
9
|
+
private ready;
|
|
10
|
+
constructor(config: OpenAISTTConfig);
|
|
11
|
+
transcribe(audioPath: string): Promise<string>;
|
|
12
|
+
isReady(): boolean;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/stt/providers/openai.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,iBAAkB,YAAW,WAAW;IACnD,IAAI,SAAoB;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,eAAe;IAc7B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAepD,OAAO,IAAI,OAAO;CAGnB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
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.OpenAISTTProvider = void 0;
|
|
40
|
+
const openai_1 = __importDefault(require("openai"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
class OpenAISTTProvider {
|
|
43
|
+
name = 'openai-whisper';
|
|
44
|
+
config;
|
|
45
|
+
client;
|
|
46
|
+
ready = false;
|
|
47
|
+
constructor(config) {
|
|
48
|
+
this.config = config;
|
|
49
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
50
|
+
if (!apiKey) {
|
|
51
|
+
console.warn('OPENAI_API_KEY not set. OpenAI STT will not work.');
|
|
52
|
+
this.client = null;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.client = new openai_1.default({ apiKey });
|
|
56
|
+
this.ready = true;
|
|
57
|
+
}
|
|
58
|
+
async transcribe(audioPath) {
|
|
59
|
+
if (!this.client) {
|
|
60
|
+
throw new Error('OpenAI client not initialized. Set OPENAI_API_KEY environment variable.');
|
|
61
|
+
}
|
|
62
|
+
const audioFile = fs.createReadStream(audioPath);
|
|
63
|
+
const response = await this.client.audio.transcriptions.create({
|
|
64
|
+
file: audioFile,
|
|
65
|
+
model: this.config.model,
|
|
66
|
+
});
|
|
67
|
+
return response.text;
|
|
68
|
+
}
|
|
69
|
+
isReady() {
|
|
70
|
+
return this.ready;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.OpenAISTTProvider = OpenAISTTProvider;
|
|
74
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/stt/providers/openai.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAA4B;AAC5B,uCAAyB;AAOzB,MAAa,iBAAiB;IAC5B,IAAI,GAAG,gBAAgB,CAAC;IAChB,MAAM,CAAkB;IACxB,MAAM,CAAS;IACf,KAAK,GAAG,KAAK,CAAC;IAEtB,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YAClE,IAAI,CAAC,MAAM,GAAG,IAAyB,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;QAC7F,CAAC;QAED,MAAM,SAAS,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAEjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;YAC7D,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;SACzB,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAtCD,8CAsCC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { STTProvider } from '../index';
|
|
2
|
+
export declare const SHERPA_MODELS: {
|
|
3
|
+
'whisper-tiny': {
|
|
4
|
+
name: string;
|
|
5
|
+
url: string;
|
|
6
|
+
folder: string;
|
|
7
|
+
languages: string[];
|
|
8
|
+
};
|
|
9
|
+
'whisper-base': {
|
|
10
|
+
name: string;
|
|
11
|
+
url: string;
|
|
12
|
+
folder: string;
|
|
13
|
+
languages: string[];
|
|
14
|
+
};
|
|
15
|
+
'whisper-small': {
|
|
16
|
+
name: string;
|
|
17
|
+
url: string;
|
|
18
|
+
folder: string;
|
|
19
|
+
languages: string[];
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export interface SherpaOnnxConfig {
|
|
23
|
+
model: keyof typeof SHERPA_MODELS;
|
|
24
|
+
language: string;
|
|
25
|
+
}
|
|
26
|
+
export declare class SherpaOnnxProvider implements STTProvider {
|
|
27
|
+
name: string;
|
|
28
|
+
private config;
|
|
29
|
+
private recognizer;
|
|
30
|
+
private ready;
|
|
31
|
+
constructor(config: SherpaOnnxConfig);
|
|
32
|
+
private initialize;
|
|
33
|
+
transcribe(audioPath: string): Promise<string>;
|
|
34
|
+
private readWavFile;
|
|
35
|
+
isReady(): boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Download a Sherpa-ONNX model
|
|
39
|
+
*/
|
|
40
|
+
export declare function downloadModel(modelId: keyof typeof SHERPA_MODELS): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* List available and installed models
|
|
43
|
+
*/
|
|
44
|
+
export declare function listModels(): {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
installed: boolean;
|
|
48
|
+
languages: string[];
|
|
49
|
+
}[];
|
|
50
|
+
//# sourceMappingURL=sherpa-onnx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sherpa-onnx.d.ts","sourceRoot":"","sources":["../../../src/stt/providers/sherpa-onnx.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA6CvC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;CAmBzB,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,OAAO,aAAa,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,kBAAmB,YAAW,WAAW;IACpD,IAAI,SAAiB;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,gBAAgB;YAKtB,UAAU;IA4ClB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAuBtC,WAAW;IAezB,OAAO,IAAI,OAAO;CAGnB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,OAAO,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CtF;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAOpG"}
|
|
@@ -0,0 +1,237 @@
|
|
|
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.SherpaOnnxProvider = exports.SHERPA_MODELS = void 0;
|
|
37
|
+
exports.downloadModel = downloadModel;
|
|
38
|
+
exports.listModels = listModels;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const MODELS_DIR = path.join(os.homedir(), '.claude-voice', 'models');
|
|
43
|
+
// Set up library path for sherpa-onnx native bindings
|
|
44
|
+
function setupLibraryPath() {
|
|
45
|
+
const platform = os.platform();
|
|
46
|
+
const arch = os.arch();
|
|
47
|
+
let platformPackage = '';
|
|
48
|
+
if (platform === 'darwin' && arch === 'arm64') {
|
|
49
|
+
platformPackage = 'sherpa-onnx-darwin-arm64';
|
|
50
|
+
}
|
|
51
|
+
else if (platform === 'darwin' && arch === 'x64') {
|
|
52
|
+
platformPackage = 'sherpa-onnx-darwin-x64';
|
|
53
|
+
}
|
|
54
|
+
else if (platform === 'linux' && arch === 'x64') {
|
|
55
|
+
platformPackage = 'sherpa-onnx-linux-x64';
|
|
56
|
+
}
|
|
57
|
+
else if (platform === 'linux' && arch === 'arm64') {
|
|
58
|
+
platformPackage = 'sherpa-onnx-linux-arm64';
|
|
59
|
+
}
|
|
60
|
+
if (platformPackage) {
|
|
61
|
+
// Try to find the package in node_modules
|
|
62
|
+
const possiblePaths = [
|
|
63
|
+
path.join(__dirname, '..', '..', '..', 'node_modules', platformPackage),
|
|
64
|
+
path.join(__dirname, '..', '..', 'node_modules', platformPackage),
|
|
65
|
+
path.join(process.cwd(), 'node_modules', platformPackage),
|
|
66
|
+
];
|
|
67
|
+
for (const libPath of possiblePaths) {
|
|
68
|
+
if (fs.existsSync(libPath)) {
|
|
69
|
+
const envVar = platform === 'darwin' ? 'DYLD_LIBRARY_PATH' : 'LD_LIBRARY_PATH';
|
|
70
|
+
const current = process.env[envVar] || '';
|
|
71
|
+
if (!current.includes(libPath)) {
|
|
72
|
+
process.env[envVar] = libPath + (current ? ':' + current : '');
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Initialize library path
|
|
80
|
+
setupLibraryPath();
|
|
81
|
+
// Available models for download
|
|
82
|
+
exports.SHERPA_MODELS = {
|
|
83
|
+
'whisper-tiny': {
|
|
84
|
+
name: 'Whisper Tiny (75MB)',
|
|
85
|
+
url: 'https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-whisper-tiny.tar.bz2',
|
|
86
|
+
folder: 'sherpa-onnx-whisper-tiny',
|
|
87
|
+
languages: ['en', 'tr', 'de', 'fr', 'es', 'it', 'pt', 'nl', 'pl', 'ru', 'zh', 'ja', 'ko'],
|
|
88
|
+
},
|
|
89
|
+
'whisper-base': {
|
|
90
|
+
name: 'Whisper Base (142MB)',
|
|
91
|
+
url: 'https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-whisper-base.tar.bz2',
|
|
92
|
+
folder: 'sherpa-onnx-whisper-base',
|
|
93
|
+
languages: ['en', 'tr', 'de', 'fr', 'es', 'it', 'pt', 'nl', 'pl', 'ru', 'zh', 'ja', 'ko'],
|
|
94
|
+
},
|
|
95
|
+
'whisper-small': {
|
|
96
|
+
name: 'Whisper Small (488MB)',
|
|
97
|
+
url: 'https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-whisper-small.tar.bz2',
|
|
98
|
+
folder: 'sherpa-onnx-whisper-small',
|
|
99
|
+
languages: ['en', 'tr', 'de', 'fr', 'es', 'it', 'pt', 'nl', 'pl', 'ru', 'zh', 'ja', 'ko'],
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
class SherpaOnnxProvider {
|
|
103
|
+
name = 'sherpa-onnx';
|
|
104
|
+
config;
|
|
105
|
+
recognizer = null;
|
|
106
|
+
ready = false;
|
|
107
|
+
constructor(config) {
|
|
108
|
+
this.config = config;
|
|
109
|
+
this.initialize();
|
|
110
|
+
}
|
|
111
|
+
async initialize() {
|
|
112
|
+
const modelInfo = exports.SHERPA_MODELS[this.config.model];
|
|
113
|
+
if (!modelInfo) {
|
|
114
|
+
console.error(`Unknown model: ${this.config.model}`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const modelPath = path.join(MODELS_DIR, modelInfo.folder);
|
|
118
|
+
if (!fs.existsSync(modelPath)) {
|
|
119
|
+
console.warn(`Model not found: ${modelPath}`);
|
|
120
|
+
console.warn(`Run: claude-voice model download ${this.config.model}`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const { OfflineRecognizer } = require('sherpa-onnx-node/non-streaming-asr');
|
|
125
|
+
// Model file naming: whisper-tiny -> tiny-encoder.onnx, etc.
|
|
126
|
+
const modelPrefix = this.config.model.replace('whisper-', '');
|
|
127
|
+
// Configure for whisper model
|
|
128
|
+
this.recognizer = new OfflineRecognizer({
|
|
129
|
+
modelConfig: {
|
|
130
|
+
whisper: {
|
|
131
|
+
encoder: path.join(modelPath, `${modelPrefix}-encoder.onnx`),
|
|
132
|
+
decoder: path.join(modelPath, `${modelPrefix}-decoder.onnx`),
|
|
133
|
+
language: this.config.language || 'en',
|
|
134
|
+
task: 'transcribe',
|
|
135
|
+
},
|
|
136
|
+
tokens: path.join(modelPath, `${modelPrefix}-tokens.txt`),
|
|
137
|
+
numThreads: 2,
|
|
138
|
+
debug: false,
|
|
139
|
+
provider: 'cpu',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
this.ready = true;
|
|
143
|
+
console.log(`Sherpa-ONNX initialized with model: ${this.config.model}`);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error('Failed to initialize Sherpa-ONNX:', error);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async transcribe(audioPath) {
|
|
150
|
+
if (!this.ready || !this.recognizer) {
|
|
151
|
+
throw new Error('Sherpa-ONNX not initialized. Download a model first.');
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
// Read WAV file
|
|
155
|
+
const samples = await this.readWavFile(audioPath);
|
|
156
|
+
// Create stream and process
|
|
157
|
+
const stream = this.recognizer.createStream();
|
|
158
|
+
stream.acceptWaveform({ samples, sampleRate: 16000 });
|
|
159
|
+
this.recognizer.decode(stream);
|
|
160
|
+
const result = this.recognizer.getResult(stream);
|
|
161
|
+
return result.text?.trim() || '';
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error('Transcription error:', error);
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async readWavFile(filePath) {
|
|
169
|
+
const buffer = fs.readFileSync(filePath);
|
|
170
|
+
// Parse WAV header (skip first 44 bytes for standard WAV)
|
|
171
|
+
const dataStart = 44;
|
|
172
|
+
const samples = new Float32Array((buffer.length - dataStart) / 2);
|
|
173
|
+
for (let i = 0; i < samples.length; i++) {
|
|
174
|
+
const sample = buffer.readInt16LE(dataStart + i * 2);
|
|
175
|
+
samples[i] = sample / 32768.0; // Normalize to [-1, 1]
|
|
176
|
+
}
|
|
177
|
+
return samples;
|
|
178
|
+
}
|
|
179
|
+
isReady() {
|
|
180
|
+
return this.ready;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.SherpaOnnxProvider = SherpaOnnxProvider;
|
|
184
|
+
/**
|
|
185
|
+
* Download a Sherpa-ONNX model
|
|
186
|
+
*/
|
|
187
|
+
async function downloadModel(modelId) {
|
|
188
|
+
const modelInfo = exports.SHERPA_MODELS[modelId];
|
|
189
|
+
if (!modelInfo) {
|
|
190
|
+
throw new Error(`Unknown model: ${modelId}`);
|
|
191
|
+
}
|
|
192
|
+
const modelPath = path.join(MODELS_DIR, modelInfo.folder);
|
|
193
|
+
if (fs.existsSync(modelPath)) {
|
|
194
|
+
console.log(`Model already exists: ${modelPath}`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Create models directory
|
|
198
|
+
if (!fs.existsSync(MODELS_DIR)) {
|
|
199
|
+
fs.mkdirSync(MODELS_DIR, { recursive: true });
|
|
200
|
+
}
|
|
201
|
+
console.log(`Downloading ${modelInfo.name}...`);
|
|
202
|
+
console.log(`URL: ${modelInfo.url}`);
|
|
203
|
+
const { execSync } = require('child_process');
|
|
204
|
+
const archivePath = path.join(MODELS_DIR, `${modelId}.tar.bz2`);
|
|
205
|
+
try {
|
|
206
|
+
// Download with curl
|
|
207
|
+
execSync(`curl -L -o "${archivePath}" "${modelInfo.url}"`, {
|
|
208
|
+
stdio: 'inherit',
|
|
209
|
+
cwd: MODELS_DIR
|
|
210
|
+
});
|
|
211
|
+
// Extract
|
|
212
|
+
console.log('Extracting...');
|
|
213
|
+
execSync(`tar -xjf "${archivePath}"`, {
|
|
214
|
+
stdio: 'inherit',
|
|
215
|
+
cwd: MODELS_DIR
|
|
216
|
+
});
|
|
217
|
+
// Cleanup archive
|
|
218
|
+
fs.unlinkSync(archivePath);
|
|
219
|
+
console.log(`Model installed: ${modelPath}`);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
console.error('Download failed:', error);
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* List available and installed models
|
|
228
|
+
*/
|
|
229
|
+
function listModels() {
|
|
230
|
+
return Object.entries(exports.SHERPA_MODELS).map(([id, info]) => ({
|
|
231
|
+
id,
|
|
232
|
+
name: info.name,
|
|
233
|
+
installed: fs.existsSync(path.join(MODELS_DIR, info.folder)),
|
|
234
|
+
languages: info.languages,
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=sherpa-onnx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sherpa-onnx.js","sourceRoot":"","sources":["../../../src/stt/providers/sherpa-onnx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { STTProvider } from '../index';
|
|
2
|
+
export interface WhisperLocalConfig {
|
|
3
|
+
model: 'tiny' | 'base' | 'small' | 'medium' | 'large';
|
|
4
|
+
device: 'cpu' | 'cuda';
|
|
5
|
+
language?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class WhisperLocalProvider implements STTProvider {
|
|
8
|
+
name: string;
|
|
9
|
+
private config;
|
|
10
|
+
private pythonServicePath;
|
|
11
|
+
private ready;
|
|
12
|
+
constructor(config: WhisperLocalConfig);
|
|
13
|
+
private checkDependencies;
|
|
14
|
+
private runCommand;
|
|
15
|
+
transcribe(audioPath: string): Promise<string>;
|
|
16
|
+
private transcribeWithCLI;
|
|
17
|
+
isReady(): boolean;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=whisper-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whisper-local.d.ts","sourceRoot":"","sources":["../../../src/stt/providers/whisper-local.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACtD,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,oBAAqB,YAAW,WAAW;IACtD,IAAI,SAAmB;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,kBAAkB;YAQxB,iBAAiB;IAY/B,OAAO,CAAC,UAAU;IA0BZ,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YA8BtC,iBAAiB;IA2B/B,OAAO,IAAI,OAAO;CAGnB"}
|
|
@@ -0,0 +1,141 @@
|
|
|
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.WhisperLocalProvider = void 0;
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class WhisperLocalProvider {
|
|
40
|
+
name = 'whisper-local';
|
|
41
|
+
config;
|
|
42
|
+
pythonServicePath;
|
|
43
|
+
ready = false;
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.pythonServicePath = path.join(__dirname, '..', '..', '..', 'python', 'stt_service.py');
|
|
47
|
+
// Check if Python and whisper are available
|
|
48
|
+
this.checkDependencies();
|
|
49
|
+
}
|
|
50
|
+
async checkDependencies() {
|
|
51
|
+
try {
|
|
52
|
+
await this.runCommand('python3', ['--version']);
|
|
53
|
+
// We'll assume whisper is installed if python3 is available
|
|
54
|
+
// The actual check happens when we try to use it
|
|
55
|
+
this.ready = true;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
console.warn('Python3 not found. Local Whisper STT will not work.');
|
|
59
|
+
this.ready = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
runCommand(command, args) {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const proc = (0, child_process_1.spawn)(command, args);
|
|
65
|
+
let stdout = '';
|
|
66
|
+
let stderr = '';
|
|
67
|
+
proc.stdout.on('data', (data) => {
|
|
68
|
+
stdout += data.toString();
|
|
69
|
+
});
|
|
70
|
+
proc.stderr.on('data', (data) => {
|
|
71
|
+
stderr += data.toString();
|
|
72
|
+
});
|
|
73
|
+
proc.on('close', (code) => {
|
|
74
|
+
if (code === 0) {
|
|
75
|
+
resolve(stdout);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
reject(new Error(stderr || `Command failed with code ${code}`));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
proc.on('error', reject);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async transcribe(audioPath) {
|
|
85
|
+
if (!this.ready) {
|
|
86
|
+
throw new Error('Whisper local provider not ready. Ensure Python3 and openai-whisper are installed.');
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Call the Python STT service script
|
|
90
|
+
const result = await this.runCommand('python3', [
|
|
91
|
+
this.pythonServicePath,
|
|
92
|
+
'--audio',
|
|
93
|
+
audioPath,
|
|
94
|
+
'--model',
|
|
95
|
+
this.config.model,
|
|
96
|
+
'--language',
|
|
97
|
+
this.config.language || 'en',
|
|
98
|
+
]);
|
|
99
|
+
// Parse the JSON result
|
|
100
|
+
const response = JSON.parse(result.trim());
|
|
101
|
+
if (response.error) {
|
|
102
|
+
throw new Error(response.error);
|
|
103
|
+
}
|
|
104
|
+
return response.transcript || '';
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// Fallback: try using whisper CLI directly
|
|
108
|
+
return this.transcribeWithCLI(audioPath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async transcribeWithCLI(audioPath) {
|
|
112
|
+
const result = await this.runCommand('whisper', [
|
|
113
|
+
audioPath,
|
|
114
|
+
'--model',
|
|
115
|
+
this.config.model,
|
|
116
|
+
'--language',
|
|
117
|
+
this.config.language || 'en',
|
|
118
|
+
'--output_format',
|
|
119
|
+
'txt',
|
|
120
|
+
'--output_dir',
|
|
121
|
+
'/tmp',
|
|
122
|
+
]);
|
|
123
|
+
// The output file will be in /tmp with the same name as the audio file but .txt extension
|
|
124
|
+
const outputPath = `/tmp/${path.basename(audioPath, path.extname(audioPath))}.txt`;
|
|
125
|
+
try {
|
|
126
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
127
|
+
const transcript = fs.readFileSync(outputPath, 'utf-8').trim();
|
|
128
|
+
fs.unlinkSync(outputPath); // Cleanup
|
|
129
|
+
return transcript;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// If we can't read the file, try parsing stdout
|
|
133
|
+
return result.trim();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
isReady() {
|
|
137
|
+
return this.ready;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.WhisperLocalProvider = WhisperLocalProvider;
|
|
141
|
+
//# sourceMappingURL=whisper-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whisper-local.js","sourceRoot":"","sources":["../../../src/stt/providers/whisper-local.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface InputInjectorOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Target terminal application
|
|
4
|
+
*/
|
|
5
|
+
terminal?: 'Terminal' | 'iTerm' | 'auto';
|
|
6
|
+
/**
|
|
7
|
+
* Whether to simulate pressing Enter after typing
|
|
8
|
+
*/
|
|
9
|
+
pressEnter?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Delay between characters in milliseconds (for slow typing effect)
|
|
12
|
+
*/
|
|
13
|
+
typingDelay?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Injects text into the terminal using AppleScript on macOS.
|
|
17
|
+
* This allows voice-transcribed text to be sent to Claude Code.
|
|
18
|
+
*/
|
|
19
|
+
export declare class TerminalInputInjector {
|
|
20
|
+
private terminal;
|
|
21
|
+
constructor(options?: InputInjectorOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Types text into the active terminal window
|
|
24
|
+
*/
|
|
25
|
+
type(text: string, pressEnter?: boolean): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Runs an AppleScript, handling multi-line scripts properly
|
|
28
|
+
*/
|
|
29
|
+
private runAppleScript;
|
|
30
|
+
/**
|
|
31
|
+
* Types text character by character with a delay (for visual effect)
|
|
32
|
+
*/
|
|
33
|
+
typeSlowly(text: string, delayMs?: number, pressEnter?: boolean): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Simulates pressing a key
|
|
36
|
+
*/
|
|
37
|
+
pressKey(key: string): Promise<void>;
|
|
38
|
+
private generateAppleScript;
|
|
39
|
+
private escapeForAppleScript;
|
|
40
|
+
private getKeyCode;
|
|
41
|
+
private delay;
|
|
42
|
+
/**
|
|
43
|
+
* Check if we're running inside a terminal
|
|
44
|
+
*/
|
|
45
|
+
static isInTerminal(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Detect the current terminal application
|
|
48
|
+
*/
|
|
49
|
+
static detectTerminal(): 'Terminal' | 'iTerm' | 'unknown';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convenience function to send voice-transcribed text to Claude Code
|
|
53
|
+
*/
|
|
54
|
+
export declare function sendToClaudeCode(text: string): Promise<void>;
|
|
55
|
+
//# sourceMappingURL=input-injector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-injector.d.ts","sourceRoot":"","sources":["../../src/terminal/input-injector.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IAEzC;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,OAAO,GAAE,oBAAyB;IAS9C;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB1D;;OAEG;YACW,cAAc;IAO5B;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAK,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9E;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1C,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,UAAU;IAwClB,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,OAAO;IAI9B;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,UAAU,GAAG,OAAO,GAAG,SAAS;CAa1D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE"}
|