fix: resolve Python detection and backend packaging issues (#241)

* fix: resolve Python detection and backend packaging issues

- Fix backend packaging path (auto-claude -> backend) to match path-resolver.ts expectations
- Add future annotations import to config_parser.py for Python 3.9+ compatibility
- Use findPythonCommand() in project-context-handlers to prioritize Homebrew Python
- Improve Python detection to prefer Homebrew paths over system Python on macOS

This resolves the following issues:
- 'analyzer.py not found' error due to incorrect packaging destination
- TypeError with 'dict | None' syntax on Python < 3.10
- Wrong Python interpreter being used (system Python instead of Homebrew Python 3.10+)

Tested on macOS with packaged app - project index now loads successfully.

* refactor: address PR review feedback

- Extract findHomebrewPython() helper to eliminate code duplication between
  findPythonCommand() and getDefaultPythonCommand()
- Remove hardcoded version-specific paths (python3.12) and rely only on
  generic Homebrew symlinks for better maintainability
- Remove unnecessary 'from __future__ import annotations' from config_parser.py
  since backend requires Python 3.12+ where union types are native

These changes make the code more maintainable, less fragile to Python version
changes, and properly reflect the project's Python 3.12+ requirement.
This commit is contained in:
HSSAINI Saad
2025-12-24 14:03:49 +01:00
committed by GitHub
parent 5ccdb6abc5
commit 0f7d6e0530
4 changed files with 43 additions and 11 deletions
+1 -1
View File
@@ -65,7 +65,7 @@
"@types/uuid": "^10.0.0",
"@vitejs/plugin-react": "^5.1.2",
"autoprefixer": "^10.4.22",
"electron": "^39.2.6",
"electron": "^39.2.7",
"electron-builder": "^26.0.12",
"electron-vite": "^5.0.0",
"eslint": "^9.39.1",
+1 -1
View File
@@ -149,7 +149,7 @@
},
{
"from": "../backend",
"to": "auto-claude",
"to": "backend",
"filter": [
"!**/.git",
"!**/__pycache__",
@@ -21,7 +21,7 @@ import {
buildMemoryStatus
} from './memory-status-handlers';
import { loadFileBasedMemories } from './memory-data-handlers';
import { parsePythonCommand } from '../../python-detector';
import { findPythonCommand, parsePythonCommand } from '../../python-detector';
/**
* Load project index from file
@@ -159,7 +159,7 @@ export function registerProjectContextHandlers(
const indexOutputPath = path.join(project.path, AUTO_BUILD_PATHS.PROJECT_INDEX);
// Get Python command directly from settings file (not pythonEnvManager which creates NEW venv)
let pythonCmd = 'python3';
let pythonCmd = findPythonCommand() || 'python3';
try {
const settingsPath = path.join(app.getPath('userData'), 'settings.json');
if (existsSync(settingsPath)) {
+39 -7
View File
@@ -1,6 +1,27 @@
import { execSync } from 'child_process';
import { existsSync } from 'fs';
/**
* Find the first existing Homebrew Python installation.
* Checks common Homebrew paths for Python 3.
*
* @returns The path to Homebrew Python, or null if not found
*/
function findHomebrewPython(): string | null {
const homebrewPaths = [
'/opt/homebrew/bin/python3', // Apple Silicon (M1/M2/M3)
'/usr/local/bin/python3' // Intel Mac
];
for (const path of homebrewPaths) {
if (existsSync(path)) {
return path;
}
}
return null;
}
/**
* Detect and return the best available Python command.
* Tries multiple candidates and returns the first one that works with Python 3.
@@ -10,11 +31,16 @@ import { existsSync } from 'fs';
export function findPythonCommand(): string | null {
const isWindows = process.platform === 'win32';
// On Windows, try py launcher first (most reliable), then python, then python3
// On Unix, try python3 first, then python
const candidates = isWindows
? ['py -3', 'python', 'python3', 'py']
: ['python3', 'python'];
// Build candidate list prioritizing Homebrew Python on macOS
let candidates: string[];
if (isWindows) {
candidates = ['py -3', 'python', 'python3', 'py'];
} else {
const homebrewPython = findHomebrewPython();
candidates = homebrewPython
? [homebrewPython, 'python3', 'python']
: ['python3', 'python'];
}
for (const cmd of candidates) {
try {
@@ -35,7 +61,10 @@ export function findPythonCommand(): string | null {
}
// Fallback to platform-specific default
return isWindows ? 'python' : 'python3';
if (isWindows) {
return 'python';
}
return findHomebrewPython() || 'python3';
}
/**
@@ -110,7 +139,10 @@ function validatePythonVersion(pythonCmd: string): {
* @returns The default Python command for this platform
*/
export function getDefaultPythonCommand(): string {
return process.platform === 'win32' ? 'python' : 'python3';
if (process.platform === 'win32') {
return 'python';
}
return findHomebrewPython() || 'python3';
}
/**