feat: Add browser-only launch mode for Kaspersky bypass

- Add `ui.launchBrowser` config option to launch browser directly
- Fix sidecar_manager to support packaged mode paths
- Set BROWSER_MODE env var for backend sidecar management
- Skip Electron window when browser-only mode enabled

Usage: Set `"ui": { "launchBrowser": true }` in config.json
to bypass Kaspersky blocking by using system browser instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-22 18:15:45 +08:00
parent 771655e03e
commit fd203ef771
3 changed files with 93 additions and 10 deletions

View File

@@ -36,16 +36,41 @@ class SidecarManager:
self._reader_thread: Optional[Thread] = None
self._progress_callbacks: list[Callable] = []
self._last_status: Dict[str, Any] = {}
self._is_packaged = getattr(sys, 'frozen', False)
# Paths
self.project_dir = Path(__file__).parent.parent.parent
self.sidecar_dir = self.project_dir / "sidecar"
self.transcriber_path = self.sidecar_dir / "transcriber.py"
self.venv_python = self.sidecar_dir / "venv" / "bin" / "python"
# Paths - detect packaged vs development mode
if self._is_packaged:
# Packaged mode: executable at resources/backend/backend/backend.exe
# Sidecar at resources/sidecar/transcriber/transcriber.exe
exec_dir = Path(sys.executable).parent.parent # up from backend/backend.exe
resources_dir = exec_dir.parent # up from backend/ to resources/
self.sidecar_dir = resources_dir / "sidecar" / "transcriber"
self.transcriber_path = self.sidecar_dir / ("transcriber.exe" if sys.platform == "win32" else "transcriber")
self.venv_python = None # Not used in packaged mode
print(f"[Sidecar] Packaged mode: transcriber={self.transcriber_path}")
else:
# Development mode
self.project_dir = Path(__file__).parent.parent.parent
self.sidecar_dir = self.project_dir / "sidecar"
self.transcriber_path = self.sidecar_dir / "transcriber.py"
if sys.platform == "win32":
self.venv_python = self.sidecar_dir / "venv" / "Scripts" / "python.exe"
else:
self.venv_python = self.sidecar_dir / "venv" / "bin" / "python"
print(f"[Sidecar] Development mode: transcriber={self.transcriber_path}")
def is_available(self) -> bool:
"""Check if sidecar is available (files exist)."""
return self.transcriber_path.exists() and self.venv_python.exists()
if self._is_packaged:
# In packaged mode, just check the executable
available = self.transcriber_path.exists()
print(f"[Sidecar] is_available (packaged): {available}, path={self.transcriber_path}")
return available
else:
# Development mode - need both script and venv
available = self.transcriber_path.exists() and self.venv_python.exists()
print(f"[Sidecar] is_available (dev): {available}, script={self.transcriber_path.exists()}, venv={self.venv_python.exists()}")
return available
def get_status(self) -> Dict[str, Any]:
"""Get current sidecar status."""
@@ -68,7 +93,6 @@ class SidecarManager:
return True # Already running
if not self.is_available():
print(f"[Sidecar] Not available: transcriber={self.transcriber_path.exists()}, venv={self.venv_python.exists()}")
return False
try:
@@ -80,13 +104,25 @@ class SidecarManager:
print(f"[Sidecar] Starting with model={env['WHISPER_MODEL']}, device={env['WHISPER_DEVICE']}, compute={env['WHISPER_COMPUTE']}")
# Build command based on mode
if self._is_packaged:
# Packaged mode: run the executable directly
cmd = [str(self.transcriber_path)]
cwd = str(self.sidecar_dir)
else:
# Development mode: use venv python
cmd = [str(self.venv_python), str(self.transcriber_path), "--server"]
cwd = str(self.sidecar_dir.parent) if self._is_packaged else str(self.sidecar_dir)
print(f"[Sidecar] Command: {cmd}, cwd={cwd}")
self.process = subprocess.Popen(
[str(self.venv_python), str(self.transcriber_path), "--server"],
cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
cwd=str(self.sidecar_dir),
cwd=cwd,
bufsize=1, # Line buffered
text=True
)