Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c6a1c59
feat(pipeline): end-to-end voice translation — STT, LLM, TTS, BlackHo…
AlleyBo55 Apr 22, 2026
12c427c
fix(pipeline): TTS drops audio after reconnect — delay queue flush 50…
AlleyBo55 Apr 22, 2026
ac32c63
fix(pipeline): wait 500ms after TTS reconnect before sending text
AlleyBo55 Apr 22, 2026
8475f1d
refactor(pipeline): replace WebSocket TTS with REST API — no more rec…
AlleyBo55 Apr 22, 2026
171d1ac
refactor(pipeline): serial utterance queue — no drops, in order, like…
AlleyBo55 Apr 22, 2026
853433c
fix: remove stale #translateAndSpeak reference — use #enqueueUtterance
AlleyBo55 Apr 22, 2026
ae7b1f9
feat(pipeline): PTT mode, STT fixes, speaker playback, prerequisites …
AlleyBo55 Apr 22, 2026
bc1c5b1
fix(pipeline): language change restart, PTT buffer reset, watchdog spam
AlleyBo55 Apr 22, 2026
2c1d035
fix(audio): per-utterance ffmpeg output, no buffering
AlleyBo55 Apr 22, 2026
8db723d
docs: README with screenshots, demo video, reel project
AlleyBo55 Apr 23, 2026
877b083
chore: remove demo.mov from repo, use GitHub Issues upload instead
AlleyBo55 Apr 23, 2026
2894455
feat(ui): add listening indicator with spectrum animation to push-to-…
AlleyBo55 Apr 23, 2026
fca7644
ci: add GitHub Actions workflows for macOS, Windows, and Linux builds
AlleyBo55 Apr 23, 2026
acba896
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
df0c3bc
fix(ci): use project-specific tsconfigs for typecheck to resolve JSX …
AlleyBo55 Apr 23, 2026
9764cf2
fix(ui): restore PTT listening indicator with spectrum animation
AlleyBo55 Apr 23, 2026
3567aae
fix(tts): reload voice profile before each TTS call to prevent stale …
AlleyBo55 Apr 23, 2026
f6ff4b6
fix(audio): remove speaker playback to prevent double audio output
AlleyBo55 Apr 23, 2026
4279d05
fix(pipeline): stop STT reconnect loop in PTT mode
AlleyBo55 Apr 23, 2026
4da37dd
fix(audio): fix garbled TTS output — use WAV file instead of raw pipe…
AlleyBo55 Apr 23, 2026
7ec8d7f
ci: add electron-builder packaging for macOS, Windows, and Linux
AlleyBo55 Apr 23, 2026
bcb6cb9
fix(audio): switch to MP3 output + sox for clean BlackHole playback
AlleyBo55 Apr 23, 2026
cb75e08
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
a26d489
chore: update package-lock.json with electron-builder dependency
AlleyBo55 Apr 23, 2026
4a986fe
fix(audio): fix BlackHole output + add speaker playback for local mon…
AlleyBo55 Apr 23, 2026
2394072
fix(audio): remove afplay speaker playback to prevent double audio on…
AlleyBo55 Apr 23, 2026
54cf238
fix(audio): play through speakers in parallel with BlackHole for loca…
AlleyBo55 Apr 23, 2026
0ed490e
fix(tts): improve voice quality — higher stability, speaker boost, 19…
AlleyBo55 Apr 23, 2026
da5aff7
fix(tts): switch to multilingual_v2 model for natural language-specif…
AlleyBo55 Apr 23, 2026
1a72756
fix(audio): boost TTS output volume 3x via ffmpeg volume filter
AlleyBo55 Apr 23, 2026
31a7afc
fix(audio): use loudnorm + volume boost for consistent loud output
AlleyBo55 Apr 23, 2026
e7e6cc0
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
2a87bca
fix(audio): remove dual playback that caused reverb — BlackHole only
AlleyBo55 Apr 23, 2026
6cd04b1
fix(audio): restore #bhIdx field declaration and fix destroy cleanup
AlleyBo55 Apr 23, 2026
535976e
fix(audio): boost volume 6x — pre-amplify MP3 before both outputs
AlleyBo55 Apr 23, 2026
61169a8
fix(ci): fix rootDir for tsconfig.main.json and type errors in native…
AlleyBo55 Apr 23, 2026
c5554f9
fix(audio): single output only — play through speakers/headphones, no…
AlleyBo55 Apr 23, 2026
e775c20
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
26aab41
fix(ci): resolve all TypeScript strict mode errors for CI build
AlleyBo55 Apr 23, 2026
d8b409c
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
b8b5bae
fix(ci): resolve unused variable errors and renderer rootDir mismatch
AlleyBo55 Apr 23, 2026
de03ea4
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
028ca3c
fix(ci): move electron to devDependencies and add author field
AlleyBo55 Apr 23, 2026
dc0540d
fix(build): use esbuild for production main+preload bundling
AlleyBo55 Apr 23, 2026
0a735d6
fix(build): add missing metadata for electron-builder packaging
AlleyBo55 Apr 23, 2026
005b6f7
fix(build): resolve ESM/CJS conflict and add custom app icon
AlleyBo55 Apr 23, 2026
c87e086
Merge branch 'master' into ci/github-workflows
AlleyBo55 Apr 23, 2026
d82f1da
fix(build): use relative asset paths for Electron file:// protocol
AlleyBo55 Apr 23, 2026
269de67
fix(ui): make production window resizable with proper sizing
AlleyBo55 Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added desktop/build/icon.icns
Binary file not shown.
Binary file added desktop/build/icon.ico
Binary file not shown.
Binary file added desktop/build/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions desktop/build/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
"version": "1.0.0",
"type": "module",
"description": "VoiceBridge Desktop — Real-time voice translation with OS-level virtual microphone",
"author": "AlleyBo55",
"main": "dist/main/main.js",
"homepage": "https://github.com/AlleyBo55/VoiceBridge",
"repository": {
"type": "git",
"url": "https://github.com/AlleyBo55/VoiceBridge.git"
},
"author": {
"name": "AlleyBo55",
"email": "alleybo55@users.noreply.github.com"
},
"main": "dist/main/main.cjs",
"scripts": {
"dev": "node scripts/dev.mjs",
"build": "npm run typecheck && node scripts/build.mjs && vite build",
"build:main": "node scripts/build.mjs",
"build:renderer": "vite build",
"start": "electron dist/main/main.js",
"start": "electron dist/main/main.cjs",
"test": "vitest run",
"typecheck": "tsc -p tsconfig.main.json --noEmit && tsc -p tsconfig.renderer.json --noEmit",
"dist:mac": "electron-builder --mac --publish never",
Expand All @@ -28,6 +36,7 @@
"dist/**/*",
"!node_modules/**/*"
],
"publish": null,
"extraResources": [],
"mac": {
"category": "public.app-category.productivity",
Expand Down
4 changes: 2 additions & 2 deletions desktop/scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ async function buildMain() {
await build({
...commonOptions,
entryPoints: [resolve(root, 'src/main/main.ts')],
outfile: resolve(root, 'dist/main/main.js'),
outfile: resolve(root, 'dist/main/main.cjs'),
define: {
'process.env.NODE_ENV': '"production"',
},
});
console.log('[build] Main process → dist/main/main.js');
console.log('[build] Main process → dist/main/main.cjs');
}

async function buildPreload() {
Expand Down
72 changes: 72 additions & 0 deletions desktop/scripts/generate-icons.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env node
/**
* Generate app icons from icon.svg for all platforms.
* Requires: macOS with sips, iconutil, and ImageMagick (convert).
*/

import { execSync } from 'child_process';
import { mkdirSync, rmSync, existsSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const buildDir = resolve(__dirname, '..', 'build');
const svgPath = resolve(buildDir, 'icon.svg');
const iconsetDir = resolve(buildDir, 'icon.iconset');

if (!existsSync(svgPath)) {
console.error('icon.svg not found in build/');
process.exit(1);
}

// Sizes needed for macOS .iconset
const sizes = [16, 32, 64, 128, 256, 512, 1024];

console.log('[icons] Generating PNGs from SVG...');

// Create iconset directory
if (existsSync(iconsetDir)) rmSync(iconsetDir, { recursive: true });
mkdirSync(iconsetDir, { recursive: true });

// Generate base 1024px PNG first
const basePng = resolve(buildDir, 'icon-1024.png');
execSync(`convert -background none -density 300 "${svgPath}" -resize 1024x1024 "${basePng}"`, { stdio: 'inherit' });

// Generate iconset PNGs for macOS
for (const size of sizes) {
const name1x = `icon_${size}x${size}.png`;
const name2x = `icon_${size / 2}x${size / 2}@2x.png`;

execSync(`sips -z ${size} ${size} "${basePng}" --out "${resolve(iconsetDir, name1x)}" 2>/dev/null`, { stdio: 'inherit' });

if (size >= 32) {
execSync(`sips -z ${size} ${size} "${basePng}" --out "${resolve(iconsetDir, name2x)}" 2>/dev/null`, { stdio: 'inherit' });
}
}

// Generate .icns for macOS
console.log('[icons] Building icon.icns...');
execSync(`iconutil -c icns "${iconsetDir}" -o "${resolve(buildDir, 'icon.icns')}"`, { stdio: 'inherit' });

// Generate 256px PNG for Linux and electron-builder fallback
console.log('[icons] Building icon.png (256px)...');
execSync(`sips -z 256 256 "${basePng}" --out "${resolve(buildDir, 'icon.png')}" 2>/dev/null`, { stdio: 'inherit' });

// Generate .ico for Windows (multi-size)
console.log('[icons] Building icon.ico...');
const icoSizes = [16, 32, 48, 64, 128, 256];
const icoInputs = icoSizes.map(s => {
const tmp = resolve(buildDir, `icon-${s}.png`);
execSync(`sips -z ${s} ${s} "${basePng}" --out "${tmp}" 2>/dev/null`, { stdio: 'inherit' });
return `"${tmp}"`;
});
execSync(`convert ${icoInputs.join(' ')} "${resolve(buildDir, 'icon.ico')}"`, { stdio: 'inherit' });

// Cleanup temp files
rmSync(iconsetDir, { recursive: true });
for (const s of [...sizes, ...icoSizes, 1024]) {
const tmp = resolve(buildDir, `icon-${s}.png`);
if (existsSync(tmp)) rmSync(tmp);
}

console.log('[icons] Done. Generated: icon.icns, icon.ico, icon.png');
15 changes: 9 additions & 6 deletions desktop/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,17 @@ function createMainWindow(): BrowserWindow {
const isDev = process.env['NODE_ENV'] === 'development';

const win = new BrowserWindow({
width: isDev ? 900 : 360,
height: isDev ? 750 : 480,
width: isDev ? 900 : 420,
height: isDev ? 750 : 680,
minWidth: 380,
minHeight: 520,
show: false,
frame: isDev,
resizable: isDev,
skipTaskbar: !isDev,
frame: true,
resizable: true,
skipTaskbar: false,
transparent: false,
backgroundColor: '#000000',
titleBarStyle: isDev ? 'default' : 'hiddenInset',
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
Expand All @@ -67,7 +70,7 @@ function createMainWindow(): BrowserWindow {
// Open DevTools in dev mode
win.webContents.openDevTools({ mode: 'detach' });
} else {
void win.loadFile(join(__dirname, '..', 'renderer', 'src', 'renderer', 'index.html'));
void win.loadFile(join(__dirname, '..', 'renderer', 'index.html'));
}

// Hide on blur (click outside) — disabled in dev for DevTools usability
Expand Down
1 change: 1 addition & 0 deletions desktop/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default defineConfig(({ mode }) => {

return {
root: resolve(__dirname, 'src/renderer'),
base: './',
plugins: [preact()],
build: {
outDir: resolve(__dirname, 'dist/renderer'),
Expand Down
Loading