Spaces:
Runtime error
Runtime error
File size: 2,976 Bytes
cd8bd0a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | "use server";
import { NextResponse } from "next/server";
import { requireCliToolsAuth } from "@/lib/api/requireCliToolsAuth";
import { getCliRuntimeStatus, CLI_TOOL_IDS } from "@/shared/services/cliRuntime";
import { getAllCliToolLastConfigured } from "@/lib/db/cliToolState";
import { checkToolConfigStatus } from "@/lib/cliTools/checkToolConfigStatus";
/**
* GET /api/cli-tools/status
* Returns runtime + config status for all CLI tools in one batch call.
* Used by the CLI Tools page to show status badges in collapsed state.
*/
export async function GET(request: Request) {
const authError = await requireCliToolsAuth(request);
if (authError) return authError;
try {
const statuses = {};
// Run all runtime checks in parallel with individual timeouts
const RUNTIME_CHECK_TIMEOUT = 5000; // 5s per tool max
await Promise.all(
CLI_TOOL_IDS.map(async (toolId) => {
try {
const runtime = (await Promise.race([
getCliRuntimeStatus(toolId),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), RUNTIME_CHECK_TIMEOUT)
),
])) as {
installed: boolean;
runnable: boolean;
command?: string;
commandPath?: string;
reason?: string;
};
statuses[toolId] = {
installed: runtime.installed,
runnable: runtime.runnable,
command: runtime.command,
commandPath: runtime.commandPath,
reason: runtime.reason || null,
};
} catch (error) {
statuses[toolId] = {
installed: false,
runnable: false,
reason: error.message || "Check failed",
};
}
})
);
// Check config status for installed+runnable tools via direct file reads
const settingsTools = [
"claude",
"codex",
"droid",
"openclaw",
"cline",
"kilo",
"qwen",
"hermes",
];
await Promise.all(
settingsTools.map(async (toolId) => {
if (!statuses[toolId]) {
return;
}
if (!statuses[toolId].installed || !statuses[toolId].runnable) {
statuses[toolId].configStatus = "not_installed";
return;
}
statuses[toolId].configStatus = await checkToolConfigStatus(toolId);
})
);
// Merge last-configured timestamps from SQLite
try {
const lastConfigured = getAllCliToolLastConfigured();
for (const [toolId, timestamp] of Object.entries(lastConfigured)) {
if (statuses[toolId]) {
statuses[toolId].lastConfiguredAt = timestamp;
}
}
} catch {
/* non-critical */
}
return NextResponse.json(statuses);
} catch (error) {
console.log("Error fetching CLI tool statuses:", error);
return NextResponse.json({ error: "Failed to fetch statuses" }, { status: 500 });
}
}
|