From 394b986ccb5817544832d3ba0aea63be343ecc9d Mon Sep 17 00:00:00 2001 From: LASTHXH Date: Sun, 29 Mar 2026 17:44:37 +0500 Subject: [PATCH] Fix CLI tools status endpoint crash and add droid detection support 1. Fixed crash in /api/cli-tools/status when statuses[toolId] is undefined - Added null check before accessing statuses[toolId] properties - Prevents "Cannot set property of undefined" error 2. Added support for droid.exe detection in ~/bin directory - Added ~/bin and ~/.local/bin to EXPECTED_PARENT_PATHS - Added droid.exe variant to toolBins for Windows - Added specific path check for droid in ~/bin/droid.exe These fixes resolve issues where CLI tools (Claude Code, Codex, Droid) were showing as "not installed" even when properly installed. Co-Authored-By: Claude Opus 4.6 --- src/app/api/cli-tools/status/route.ts | 5 ++++- src/shared/services/cliRuntime.ts | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/app/api/cli-tools/status/route.ts b/src/app/api/cli-tools/status/route.ts index 21d2ebcc93..2d8108aaf4 100644 --- a/src/app/api/cli-tools/status/route.ts +++ b/src/app/api/cli-tools/status/route.ts @@ -98,7 +98,10 @@ export async function GET() { await Promise.all( settingsTools.map(async (toolId) => { - if (!statuses[toolId]?.installed || !statuses[toolId]?.runnable) { + if (!statuses[toolId]) { + return; + } + if (!statuses[toolId].installed || !statuses[toolId].runnable) { statuses[toolId].configStatus = "not_installed"; return; } diff --git a/src/shared/services/cliRuntime.ts b/src/shared/services/cliRuntime.ts index ca3f64641c..2c06854914 100644 --- a/src/shared/services/cliRuntime.ts +++ b/src/shared/services/cliRuntime.ts @@ -327,8 +327,15 @@ const getExpectedParentPaths = (): string[] => { const npmPrefix = getNpmGlobalPrefix(); + // Add common user bin directories + const userBinPaths = [ + path.join(home, "bin"), + path.join(home, ".local", "bin"), + ]; + return [ home, + ...userBinPaths, userProfile, validatedAppData, validatedLocalAppData, @@ -374,7 +381,10 @@ const getKnownToolPaths = (toolId: string): string[] => { ["claude.exe", "claude"], ], codex: [["codex.cmd", "codex"]], - droid: [["droid.cmd", "droid"]], + droid: [ + ["droid.cmd", "droid"], + ["droid.exe", "droid"], + ], openclaw: [["openclaw.cmd", "openclaw"]], cursor: [ ["agent.cmd", "agent"], @@ -404,6 +414,10 @@ const getKnownToolPaths = (toolId: string): string[] => { } } + if (toolId === "droid") { + paths.push(path.join(home, "bin", "droid.exe")); + } + for (const [winName] of bins) { if (npmPrefix) paths.push(path.join(npmPrefix, winName)); if (appData) {