fix: community patches for production stability (OAuth, DB safety, burst-limit, CLI tools) (#1213)

Integrated into release/v3.6.5
This commit is contained in:
Hdsje
2026-04-13 19:10:27 +03:00
committed by GitHub
parent ee5a1f0e7a
commit 56f7a5baae
4 changed files with 54 additions and 11 deletions

View File

@@ -253,7 +253,12 @@ export class AntigravityExecutor extends BaseExecutor {
if (match[2]) totalMs += parseInt(match[2]) * 60 * 1000; // minutes
if (match[3]) totalMs += parseInt(match[3]) * 1000; // seconds
return totalMs > 0 ? totalMs : null;
// "reset after 0s" = burst/RPM limit, not quota exhaustion.
// Return a minimum backoff so the auto-retry loop handles it
// instead of falling through to the 24h exhaustion classifier.
if (totalMs === 0) return 2_000; // 2s minimum burst-limit backoff
return totalMs;
}
/**

View File

@@ -20,28 +20,62 @@ async function checkToolConfigStatus(toolId: string): Promise<string> {
if (!configPath) return "unknown";
const content = await fs.readFile(configPath, "utf-8");
// Codex uses TOML config — parse as raw text, not JSON
if (toolId === "codex") {
const lower = content.toLowerCase();
const hasOmniRoute =
lower.includes("omniroute") ||
lower.includes(`localhost:${apiPort}`) ||
lower.includes(`127.0.0.1:${apiPort}`);
if (!hasOmniRoute) return "not_configured";
// Also verify auth.json has an API key (not masked/empty)
try {
const authPath = configPath.replace(/config\.toml$/, "auth.json");
const authContent = await fs.readFile(authPath, "utf-8");
const auth = JSON.parse(authContent);
const apiKey = auth?.OPENAI_API_KEY || "";
if (!apiKey || apiKey.includes("****") || apiKey.length < 20) {
return "not_configured";
}
} catch {
return "not_configured";
}
return "configured";
}
const config = JSON.parse(content);
// Each tool stores OmniRoute config differently
switch (toolId) {
case "claude":
return config?.env?.ANTHROPIC_BASE_URL ? "configured" : "not_configured";
case "codex":
return config?.providers?.omniroute || config?.providers?.["openai-compatible"]
? "configured"
: "not_configured";
case "droid":
case "openclaw":
case "cline":
case "kilo":
// Generic check: look for OmniRoute-specific markers in the config
const configStr = JSON.stringify(config).toLowerCase();
return configStr.includes("omniroute") ||
if (
configStr.includes("omniroute") ||
configStr.includes("sk_omniroute") ||
configStr.includes(`localhost:${apiPort}`) ||
configStr.includes(`127.0.0.1:${apiPort}`)
? "configured"
: "not_configured";
) {
return "configured";
}
// Also accept openai-compatible provider with any non-empty baseUrl
// (user may configure an external domain instead of localhost)
if (
toolId === "cline" &&
(config.actModeApiProvider === "openai" || config.planModeApiProvider === "openai") &&
(config.openAiBaseUrl || "").trim().length > 0
) {
return "configured";
}
return "not_configured";
default:
return "unknown";
}

View File

@@ -532,9 +532,13 @@ export function getDbInstance(): SqliteDatabase {
}
} catch (e: unknown) {
const message = e instanceof Error ? e.message : String(e);
console.warn("[DB] Could not probe existing DB, will create fresh:", message);
console.warn("[DB] Could not probe existing DB:", message);
// SAFETY: Never delete the database — rename to backup so data can be recovered.
// The old code would silently destroy all user data on any probe failure.
const failedPath = sqliteFile + `.probe-failed-${Date.now()}`;
try {
fs.unlinkSync(sqliteFile);
fs.renameSync(sqliteFile, failedPath);
console.warn(`[DB] Renamed corrupt DB to ${path.basename(failedPath)}`);
} catch {
/* ok */
}

View File

@@ -69,7 +69,7 @@ export function startLocalServer(
// Listen on fixed port or find available port
const portToUse = fixedPort || 0;
server.listen(portToUse, "127.0.0.1", () => {
server.listen(portToUse, "0.0.0.0", () => {
const addr = server.address() as { port: number };
resolve({
server,