-
Notifications
You must be signed in to change notification settings - Fork 32
Description
Summary
The altimate-engine Python sidecar has multiple installation issues affecting both developers (bun dev mode) and end users (npm/brew install).
Bug 1: Wrong path resolution in dev mode (client.ts)
Root Cause
client.ts:24 goes up 3 levels instead of 4, pointing to a nonexistent directory:
// client.ts line 24 — BUG: resolves to packages/opencode/altimate-engine (doesn't exist)
const engineDir = path.resolve(__dirname, "..", "..", "..", "altimate-engine")
// engine.ts getEngineVersion — CORRECT: resolves to packages/altimate-engine
const pyprojectPath = path.resolve(__dirname, "../../../../altimate-engine/pyproject.toml")Both files live at the same depth (packages/opencode/src/altimate/bridge/), but client.ts uses 3 .. while engine.ts correctly uses 4.
Impact
resolvePython()step 2 never finds the local dev.venv- Falls through to managed venv (PyPI version)
- Developer's local engine changes are silently ignored
Fix
// client.ts line 24
- const engineDir = path.resolve(__dirname, "..", "..", "..", "altimate-engine")
+ const engineDir = path.resolve(__dirname, "..", "..", "..", "..", "altimate-engine")Bug 2: Engine bootstrap is lazy — no install-time setup (npm/brew)
Problem
When a user installs via npm install -g @altimateai/altimate-code or brew install altimate/tap/altimate-code:
- No
postinstallhook exists —package.jsonhas no install scripts - No explicit setup command —
EngineCommandinaltimate/cli/engine.tsis dead code (exported but never imported/registered in the CLI) - Engine bootstrap only happens at first runtime when
Bridge.call()is invoked - On first tool use, the user waits ~5-30s while uv downloads from GitHub + altimate-engine installs from PyPI
- There's no clear progress indicator (messages go to
Log.Default.infowhich usesTEXT_DIMstyling)
Expected
Either:
- A
postinstallhook that pre-installs the engine, OR - A clear first-run message explaining what's happening, OR
- Wire
EngineCommandinto the CLI soaltimate engine installworks
Reproduction
# 1. Install via npm
npm install -g @altimateai/altimate-code
# 2. Start the tool
altimate-code
# 3. Try to use any tool that calls the Python engine
# First call hangs for 5-30s with no clear feedback while:
# - uv binary downloads from GitHub
# - Python 3.12 venv is created
# - altimate-engine installs from PyPIBug 3: Python 3.12 is hardcoded — fails on systems without it
Problem
engine.ts:175 hardcodes Python 3.12:
execFileSync(uv, ["venv", "--python", "3.12", venvDir], { stdio: "pipe" })But pyproject.toml says requires-python = ">=3.10". If a user only has Python 3.10 or 3.11, the venv creation fails.
Error experience
When Python 3.12 is unavailable, ensureEngine() throws the raw execFileSync error. Since start() has no try-catch around ensureEngine() (line 108), and Bridge.call() has no catch around start(), the raw error propagates to the caller. Critically, restartCount (which gates the MAX_RESTARTS check) is only incremented when a spawned child process exits — not when ensureEngine() fails before any process starts. This means every subsequent call() retries ensureEngine() indefinitely with the same failure.
The user sees something like:
error: No download found for request: cpython@3.12
Fix
Use a version range instead of hardcoded version:
- execFileSync(uv, ["venv", "--python", "3.12", venvDir], { stdio: "pipe" })
+ execFileSync(uv, ["venv", "--python", ">=3.10,<4", venvDir], { stdio: "pipe" })Or at minimum, catch the error and provide a clear message:
Error: Python 3.12 is required but not found. Install it with:
brew install python@3.12 (macOS)
apt install python3.12 (Ubuntu/Debian)
Bug 4: No error handling around ensureEngine() in start()
Problem
The error propagation chain in Bridge.start() → Bridge.call() has a gap:
// client.ts start() — line 108: NO try-catch
async function start() {
await ensureEngine() // ← throws raw execFileSync error, unwrapped
const pythonCmd = resolvePython()
child = spawn(pythonCmd, ["-m", "altimate_engine.server"], { ... })
// ...
try {
await call("ping", {} as any)
} catch (e) {
throw new Error(`Failed to start Python bridge: ${e}`) // ← only wraps ping errors
}
}When ensureEngine() fails:
ensureEngine()throws with rawexecFileSyncstderr (technical, may be a Buffer)start()does NOT catch it — the error propagates raw tocall()call()does NOT catchstart()— the error propagates to the tool callerrestartCountis never incremented (only fires onchild.on("exit"))- Next
call()retriesensureEngine()from scratch — infinite retry loop with no backoff
The MAX_RESTARTS guard (line 55) only protects against spawned processes crashing, not against ensureEngine() failures.
Expected
async function start() {
try {
await ensureEngine()
} catch (e) {
throw new Error(`Engine setup failed: ${e instanceof Error ? e.message : String(e)}`)
}
// ...
}Plus: increment restartCount on ensureEngine() failure so MAX_RESTARTS eventually triggers.
Resolution Flow (for reference)
resolvePython() priority:
1. OPENCODE_PYTHON env var
2. packages/opencode/altimate-engine/.venv ← BUG: wrong path (3 levels, should be 4)
3. cwd/.venv
4. ~/.local/share/altimate-code/engine/venv ← managed venv (created by ensureEngine)
5. python3 fallback
ensureEngine() flow:
1. Check manifest at ~/.local/share/altimate-code/engine/manifest.json
2. If version matches → return (no-op)
3. Download uv binary from GitHub (platform-specific)
4. Create venv: uv venv --python 3.12 ← hardcoded
5. Install: uv pip install altimate-engine=={VERSION} from PyPI
6. Write manifest.json
Environment
- macOS (Darwin 25.2.0), arm64
- bun 1.x
- Key files:
packages/opencode/src/altimate/bridge/client.ts(line 24)packages/opencode/src/altimate/bridge/engine.ts(line 175)packages/opencode/bin/altimate(npm bin stub — no postinstall)packages/opencode/src/altimate/cli/engine.ts(dead code — EngineCommand never registered)