fiemwl / src /app /api /cli-tools /status /route.ts
automindy's picture
Upload 1980 files
6111b2b verified
Raw
History Blame Contribute Delete
3.07 kB
"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 });
}
}