voicecc 1.1.8 → 1.1.10
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 +46 -5
- package/dashboard/dist/assets/index-D1kvWqMD.js +11 -0
- package/dashboard/dist/index.html +1 -1
- package/dashboard/routes/agents.ts +48 -1
- package/dashboard/routes/auth.ts +157 -68
- package/init/defaults/system.md +5 -1
- package/package.json +1 -1
- package/server/index.ts +14 -6
- package/server/services/agent-store.ts +71 -0
- package/dashboard/dist/assets/index-BSLjaEDe.js +0 -11
package/bin/voicecc.js
CHANGED
|
@@ -297,12 +297,33 @@ function stopDaemon() {
|
|
|
297
297
|
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
298
298
|
console.log(`Stopping VoiceCC (PID ${pid})...`);
|
|
299
299
|
|
|
300
|
+
// Kill the entire process group (negative PID) so child processes
|
|
301
|
+
// like cloudflared and tsx's Node subprocess are also terminated.
|
|
300
302
|
try {
|
|
301
|
-
process.kill(pid, "SIGTERM");
|
|
303
|
+
process.kill(-pid, "SIGTERM");
|
|
302
304
|
} catch {
|
|
303
|
-
//
|
|
305
|
+
// Fall back to killing just the main PID
|
|
306
|
+
try { process.kill(pid, "SIGTERM"); } catch { /* already dead */ }
|
|
304
307
|
}
|
|
305
308
|
|
|
309
|
+
// Wait for the process to actually die (up to 5 seconds)
|
|
310
|
+
const deadline = Date.now() + 5000;
|
|
311
|
+
while (Date.now() < deadline) {
|
|
312
|
+
try {
|
|
313
|
+
process.kill(pid, 0);
|
|
314
|
+
} catch {
|
|
315
|
+
break; // Process is gone
|
|
316
|
+
}
|
|
317
|
+
// Busy-wait in small increments
|
|
318
|
+
const waitUntil = Date.now() + 100;
|
|
319
|
+
while (Date.now() < waitUntil) { /* spin */ }
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Force kill if still alive
|
|
323
|
+
try {
|
|
324
|
+
process.kill(-pid, "SIGKILL");
|
|
325
|
+
} catch { /* already dead */ }
|
|
326
|
+
|
|
306
327
|
// Clean up
|
|
307
328
|
try { unlinkSync(PID_FILE); } catch { /* ignore */ }
|
|
308
329
|
try { unlinkSync(STATUS_FILE); } catch { /* ignore */ }
|
|
@@ -479,10 +500,20 @@ function startDaemon() {
|
|
|
479
500
|
ensureNonRootUser();
|
|
480
501
|
chownPkgRoot();
|
|
481
502
|
console.log(`Dropping root privileges, running as '${VOICECC_USER}'...`);
|
|
482
|
-
|
|
503
|
+
|
|
504
|
+
// Resolve uid/gid for the voicecc user so we can drop privileges
|
|
505
|
+
// via spawn options instead of `su`, which can leak stdio and
|
|
506
|
+
// cause PID tracking issues.
|
|
507
|
+
const uid = parseInt(execSync(`id -u ${VOICECC_USER}`, { encoding: "utf-8" }).trim(), 10);
|
|
508
|
+
const gid = parseInt(execSync(`id -g ${VOICECC_USER}`, { encoding: "utf-8" }).trim(), 10);
|
|
509
|
+
|
|
510
|
+
child = spawn(TSX_BIN, ["server/index.ts"], {
|
|
483
511
|
cwd: PKG_ROOT,
|
|
484
512
|
detached: true,
|
|
485
513
|
stdio: ["ignore", logFd, logFd],
|
|
514
|
+
uid,
|
|
515
|
+
gid,
|
|
516
|
+
env: { ...process.env, HOME: `/home/${VOICECC_USER}`, USER: VOICECC_USER, VOICECC_DIR },
|
|
486
517
|
});
|
|
487
518
|
} else {
|
|
488
519
|
child = spawn(TSX_BIN, ["server/index.ts"], {
|
|
@@ -543,6 +574,16 @@ if (isRunning()) {
|
|
|
543
574
|
// Start the daemon
|
|
544
575
|
startDaemon();
|
|
545
576
|
|
|
546
|
-
//
|
|
547
|
-
|
|
577
|
+
// Poll for status.json until the server is ready
|
|
578
|
+
const tunnelEnabled = readFileSync(ENV_PATH, "utf-8").includes("TUNNEL_ENABLED=true");
|
|
579
|
+
const MAX_WAIT_MS = tunnelEnabled ? 30000 : 10000;
|
|
580
|
+
const POLL_INTERVAL_MS = 500;
|
|
581
|
+
const startTime = Date.now();
|
|
582
|
+
|
|
583
|
+
while (Date.now() - startTime < MAX_WAIT_MS) {
|
|
584
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
585
|
+
const status = readStatus();
|
|
586
|
+
if (status && (!tunnelEnabled || status.tunnelUrl)) break;
|
|
587
|
+
}
|
|
588
|
+
|
|
548
589
|
showInfo();
|