voicecc 1.0.8 → 1.0.9
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/bin/voicecc.js +11 -14
- package/package.json +2 -3
- package/scripts/postinstall.js +28 -58
package/bin/voicecc.js
CHANGED
|
@@ -3,31 +3,28 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* CLI entry point for the voicecc command.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* with
|
|
8
|
-
*
|
|
9
|
-
* Responsibilities:
|
|
10
|
-
* - Resolve the package root from this script's location
|
|
11
|
-
* - Spawn tsx with run.ts in the correct working directory
|
|
12
|
-
* - Forward signals (SIGINT, SIGTERM) so Ctrl+C stops the server cleanly
|
|
6
|
+
* Checks if first-run setup is needed (compile mic-vpio, Python venv, etc.)
|
|
7
|
+
* and runs it with visible output. Then spawns `tsx run.ts` for the dashboard.
|
|
13
8
|
*/
|
|
14
9
|
|
|
15
10
|
import { spawn } from "node:child_process";
|
|
16
11
|
import { dirname, join } from "node:path";
|
|
17
12
|
import { fileURLToPath } from "node:url";
|
|
18
13
|
|
|
19
|
-
// ============================================================================
|
|
20
|
-
// CONSTANTS
|
|
21
|
-
// ============================================================================
|
|
22
|
-
|
|
23
14
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
24
15
|
const PKG_ROOT = join(__dirname, "..");
|
|
25
16
|
const TSX_BIN = join(PKG_ROOT, "node_modules", ".bin", "tsx");
|
|
26
17
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
// Run setup if needed (first run or incomplete install)
|
|
19
|
+
process.chdir(PKG_ROOT);
|
|
20
|
+
const { needsSetup, runSetup } = await import("../scripts/postinstall.js");
|
|
21
|
+
|
|
22
|
+
if (needsSetup()) {
|
|
23
|
+
console.log("[voicecc] Running first-time setup...\n");
|
|
24
|
+
runSetup();
|
|
25
|
+
}
|
|
30
26
|
|
|
27
|
+
// Start the dashboard
|
|
31
28
|
const child = spawn(TSX_BIN, ["run.ts"], {
|
|
32
29
|
cwd: PKG_ROOT,
|
|
33
30
|
stdio: "inherit",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "voicecc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Voice mode plugin for Claude Code -- hands-free interaction via local STT/TTS/VAD",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"start": "tsx run.ts",
|
|
11
11
|
"dev:dashboard": "cd dashboard && npx vite",
|
|
12
12
|
"build:dashboard": "cd dashboard && npx vite build",
|
|
13
|
-
"prepublishOnly": "npm run build:dashboard"
|
|
14
|
-
"postinstall": "node scripts/postinstall.js"
|
|
13
|
+
"prepublishOnly": "npm run build:dashboard"
|
|
15
14
|
},
|
|
16
15
|
"files": [
|
|
17
16
|
"bin/",
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Setup script for voicecc.
|
|
3
3
|
*
|
|
4
4
|
* Compiles the mic-vpio Swift binary (macOS VPIO echo cancellation),
|
|
5
5
|
* checks for required system dependencies (espeak-ng), then sets up
|
|
6
6
|
* the Python virtual environment and installs TTS dependencies.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* - Compile the mic-vpio Swift binary for echo-cancelled audio I/O
|
|
10
|
-
* - Verify espeak-ng is installed
|
|
11
|
-
* - Create Python venv in sidecar/.venv (if not already present)
|
|
12
|
-
* - Install Python TTS packages (mlx-audio, misaki, etc.)
|
|
13
|
-
* - Download spaCy English model
|
|
8
|
+
* Called from bin/voicecc.js on first run (or when setup is incomplete).
|
|
14
9
|
*/
|
|
15
10
|
|
|
16
11
|
import { execSync } from "child_process";
|
|
@@ -24,6 +19,7 @@ import { join } from "path";
|
|
|
24
19
|
const VENV_DIR = join("sidecar", ".venv");
|
|
25
20
|
const PIP = join(VENV_DIR, "bin", "pip");
|
|
26
21
|
const PYTHON = join(VENV_DIR, "bin", "python3");
|
|
22
|
+
const MIC_VPIO = join("sidecar", "mic-vpio");
|
|
27
23
|
|
|
28
24
|
const PYTHON_PACKAGES = [
|
|
29
25
|
"mlx-audio",
|
|
@@ -34,10 +30,24 @@ const PYTHON_PACKAGES = [
|
|
|
34
30
|
];
|
|
35
31
|
|
|
36
32
|
// ============================================================================
|
|
37
|
-
//
|
|
33
|
+
// PUBLIC API
|
|
38
34
|
// ============================================================================
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Returns true if any setup step is incomplete.
|
|
38
|
+
*/
|
|
39
|
+
export function needsSetup() {
|
|
40
|
+
return (
|
|
41
|
+
!existsSync(MIC_VPIO) ||
|
|
42
|
+
!existsSync(PYTHON) ||
|
|
43
|
+
!existsSync(join("dashboard", "dist", "index.html"))
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Run all setup steps. Shows progress to stdout.
|
|
49
|
+
*/
|
|
50
|
+
export function runSetup() {
|
|
41
51
|
installClaudeMd();
|
|
42
52
|
buildDashboard();
|
|
43
53
|
compileMicVpio();
|
|
@@ -48,20 +58,15 @@ function main() {
|
|
|
48
58
|
|
|
49
59
|
console.log("");
|
|
50
60
|
console.log("========================================");
|
|
51
|
-
console.log("
|
|
61
|
+
console.log(" VOICECC SETUP COMPLETE ");
|
|
52
62
|
console.log("========================================");
|
|
53
63
|
console.log("");
|
|
54
|
-
console.log(" Run 'voicecc' in terminal to start the server!");
|
|
55
|
-
console.log("");
|
|
56
64
|
}
|
|
57
65
|
|
|
58
66
|
// ============================================================================
|
|
59
67
|
// HELPER FUNCTIONS
|
|
60
68
|
// ============================================================================
|
|
61
69
|
|
|
62
|
-
/**
|
|
63
|
-
* Build the dashboard frontend via Vite.
|
|
64
|
-
*/
|
|
65
70
|
function buildDashboard() {
|
|
66
71
|
if (existsSync(join("dashboard", "dist", "index.html"))) {
|
|
67
72
|
console.log("Dashboard already built, skipping.");
|
|
@@ -78,16 +83,11 @@ function buildDashboard() {
|
|
|
78
83
|
console.log("Dashboard built successfully");
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
/**
|
|
82
|
-
* Copy the project CLAUDE.md from init/ to the project root.
|
|
83
|
-
* Overwrites any existing CLAUDE.md to keep it in sync with the repo.
|
|
84
|
-
*/
|
|
85
86
|
function installClaudeMd() {
|
|
86
87
|
const src = join("init", "CLAUDE.md");
|
|
87
88
|
const dest = "CLAUDE.md";
|
|
88
89
|
|
|
89
90
|
if (!existsSync(src)) {
|
|
90
|
-
console.warn("init/CLAUDE.md not found, skipping.");
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -95,13 +95,13 @@ function installClaudeMd() {
|
|
|
95
95
|
console.log("Installed CLAUDE.md to project root.");
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
/**
|
|
99
|
-
* Compile the mic-vpio Swift binary for macOS VPIO echo cancellation.
|
|
100
|
-
* Skips compilation if the binary already exists and is newer than the source.
|
|
101
|
-
*/
|
|
102
98
|
function compileMicVpio() {
|
|
99
|
+
if (existsSync(MIC_VPIO)) {
|
|
100
|
+
console.log("mic-vpio already compiled, skipping.");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
103
104
|
const source = join("sidecar", "mic-vpio.swift");
|
|
104
|
-
const binary = join("sidecar", "mic-vpio");
|
|
105
105
|
|
|
106
106
|
if (process.platform !== "darwin") {
|
|
107
107
|
console.error("\n[voicecc] ERROR: macOS is required.");
|
|
@@ -118,7 +118,7 @@ function compileMicVpio() {
|
|
|
118
118
|
|
|
119
119
|
console.log("Compiling mic-vpio (VPIO echo cancellation)...");
|
|
120
120
|
try {
|
|
121
|
-
run(`swiftc -O -o ${
|
|
121
|
+
run(`swiftc -O -o ${MIC_VPIO} ${source} -framework AudioToolbox -framework CoreAudio`);
|
|
122
122
|
} catch (err) {
|
|
123
123
|
console.error("\n[voicecc] ERROR: Failed to compile mic-vpio.swift.");
|
|
124
124
|
console.error(" Make sure Xcode Command Line Tools are installed: xcode-select --install\n");
|
|
@@ -127,10 +127,6 @@ function compileMicVpio() {
|
|
|
127
127
|
console.log("mic-vpio compiled successfully");
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
/**
|
|
131
|
-
* Check that required system binaries are available.
|
|
132
|
-
* Exits with a clear error message if any are missing.
|
|
133
|
-
*/
|
|
134
130
|
function checkSystemDeps() {
|
|
135
131
|
const missing = [];
|
|
136
132
|
|
|
@@ -139,16 +135,13 @@ function checkSystemDeps() {
|
|
|
139
135
|
if (missing.length > 0) {
|
|
140
136
|
console.error(`\n[voicecc] ERROR: Missing system dependencies: ${missing.join(", ")}`);
|
|
141
137
|
console.error(` Install with: brew install ${missing.join(" ")}`);
|
|
142
|
-
console.error(` Then re-run:
|
|
138
|
+
console.error(` Then re-run: voicecc\n`);
|
|
143
139
|
process.exit(1);
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
console.log("System dependencies OK (espeak-ng)");
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
/**
|
|
150
|
-
* Create the Python virtual environment if it doesn't exist.
|
|
151
|
-
*/
|
|
152
145
|
function setupPythonVenv() {
|
|
153
146
|
if (existsSync(PIP)) {
|
|
154
147
|
console.log(`Python venv already exists at ${VENV_DIR}`);
|
|
@@ -171,9 +164,6 @@ function setupPythonVenv() {
|
|
|
171
164
|
}
|
|
172
165
|
}
|
|
173
166
|
|
|
174
|
-
/**
|
|
175
|
-
* Install Python TTS packages into the venv.
|
|
176
|
-
*/
|
|
177
167
|
function installPythonPackages() {
|
|
178
168
|
console.log("Installing Python TTS packages...");
|
|
179
169
|
try {
|
|
@@ -182,14 +172,11 @@ function installPythonPackages() {
|
|
|
182
172
|
console.error("\n[voicecc] ERROR: Failed to install Python TTS packages.");
|
|
183
173
|
console.error(" This may be due to missing build tools or incompatible Python version.");
|
|
184
174
|
console.error(" Required packages: " + PYTHON_PACKAGES.join(", "));
|
|
185
|
-
console.error(" Try deleting sidecar/.venv and re-running:
|
|
175
|
+
console.error(" Try deleting sidecar/.venv and re-running: voicecc\n");
|
|
186
176
|
process.exit(1);
|
|
187
177
|
}
|
|
188
178
|
}
|
|
189
179
|
|
|
190
|
-
/**
|
|
191
|
-
* Download the spaCy English language model.
|
|
192
|
-
*/
|
|
193
180
|
function downloadSpacyModel() {
|
|
194
181
|
console.log("Downloading spaCy English model...");
|
|
195
182
|
try {
|
|
@@ -201,12 +188,6 @@ function downloadSpacyModel() {
|
|
|
201
188
|
}
|
|
202
189
|
}
|
|
203
190
|
|
|
204
|
-
/**
|
|
205
|
-
* Check if a command exists on the system PATH.
|
|
206
|
-
*
|
|
207
|
-
* @param {string} cmd - Command name to check
|
|
208
|
-
* @returns {boolean} True if the command exists
|
|
209
|
-
*/
|
|
210
191
|
function commandExists(cmd) {
|
|
211
192
|
try {
|
|
212
193
|
execSync(`which ${cmd}`, { stdio: "ignore" });
|
|
@@ -216,17 +197,6 @@ function commandExists(cmd) {
|
|
|
216
197
|
}
|
|
217
198
|
}
|
|
218
199
|
|
|
219
|
-
/**
|
|
220
|
-
* Run a shell command with inherited stdio (output visible to user).
|
|
221
|
-
*
|
|
222
|
-
* @param {string} cmd - Shell command to execute
|
|
223
|
-
*/
|
|
224
200
|
function run(cmd) {
|
|
225
201
|
execSync(cmd, { stdio: "inherit" });
|
|
226
202
|
}
|
|
227
|
-
|
|
228
|
-
// ============================================================================
|
|
229
|
-
// ENTRY POINT
|
|
230
|
-
// ============================================================================
|
|
231
|
-
|
|
232
|
-
main();
|