diff --git a/ccw/src/core/routes/litellm-api-routes.ts b/ccw/src/core/routes/litellm-api-routes.ts index 8d38b575..701d6b88 100644 --- a/ccw/src/core/routes/litellm-api-routes.ts +++ b/ccw/src/core/routes/litellm-api-routes.ts @@ -662,7 +662,7 @@ export async function handleLiteLLMApiRoutes(ctx: RouteContext): Promise { try { - const { spawn } = await import('child_process'); + // Priority 1: Use UV to uninstall from CodexLens venv + if (await isUvAvailable()) { + const uv = createCodexLensUvManager(); + if (uv.isVenvValid()) { + console.log('[ccw-litellm uninstall] Using UV to uninstall from CodexLens venv...'); + const uvResult = await uv.uninstall(['ccw-litellm']); + clearCcwLitellmStatusCache(); - // Use shared Python detection for consistent cross-platform behavior + if (uvResult.success) { + broadcastToClients({ + type: 'CCW_LITELLM_UNINSTALLED', + payload: { timestamp: new Date().toISOString() } + }); + return { success: true, message: 'ccw-litellm uninstalled successfully via UV' }; + } + console.log('[ccw-litellm uninstall] UV uninstall failed, falling back to pip:', uvResult.error); + } + } + + // Priority 2: Fallback to system pip uninstall + console.log('[ccw-litellm uninstall] Using pip fallback...'); + const { spawn } = await import('child_process'); const pythonCmd = getSystemPython(); return new Promise((resolve) => {