()
| 191 | } |
| 192 | |
| 193 | private resolvePythonExecutable(): string { |
| 194 | const userData = app.getPath('userData') |
| 195 | const apiDir = this.resolveApiDir() |
| 196 | |
| 197 | // Primary: venv created during setup (bundled Python → isolated venv) |
| 198 | const venvPython = getVenvPythonExe(userData) |
| 199 | if (existsSync(venvPython)) return venvPython |
| 200 | |
| 201 | // Dev fallback: local .venv in the api directory |
| 202 | const devCandidates = [ |
| 203 | join(apiDir, '.venv', 'Scripts', 'python.exe'), |
| 204 | join(apiDir, '.venv', 'bin', 'python'), |
| 205 | ] |
| 206 | for (const c of devCandidates) { |
| 207 | if (existsSync(c)) return c |
| 208 | } |
| 209 | |
| 210 | // Never fall back to bare 'python' on Windows — it would be the user's system Python |
| 211 | if (process.platform === 'win32') { |
| 212 | throw new Error('Python venv not found. Please restart the application to re-run setup.') |
| 213 | } |
| 214 | return 'python3' |
| 215 | } |
| 216 | |
| 217 | private resolveApiDir(): string { |
| 218 | if (app.isPackaged) return join(process.resourcesPath, 'api') |
no test coverage detected