From 79154d9b3ff17fd47d8f7d0be5d317756861c9a8 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 13 May 2026 11:52:01 +0000 Subject: [PATCH] Tighten ClaudeQQ health checks in e2e --- scripts/src/e2e.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/src/e2e.ts b/scripts/src/e2e.ts index 25654cc2..fa1c9b0b 100644 --- a/scripts/src/e2e.ts +++ b/scripts/src/e2e.ts @@ -893,8 +893,8 @@ async function serviceChecks(config: UniDeskConfig, urls: PublicUrls, checks: E2 const metNonlinearQueueBody = (metNonlinearQueue as { body?: { ok?: boolean; queue?: { counts?: Record; maxConcurrency?: number; targetGpuName?: string }; jobs?: unknown[] } }).body; const metNonlinearProjectsBody = (metNonlinearProjects as { body?: { ok?: boolean; projects?: unknown[] } }).body; const metNonlinearImagesBody = (metNonlinearImages as { body?: { ok?: boolean; mlImage?: { present?: boolean; image?: string } } }).body; - const claudeqqHealthBody = (claudeqqHealth as { body?: { ok?: boolean; service?: string; endpoints?: string[]; subscriptions?: { count?: number; enabled?: number }; napcat?: { containerized?: boolean; qrcode?: { available?: boolean; dataUrl?: string } } } }).body; - const claudeqqNapcatLoginBody = (claudeqqNapcatLogin as { body?: { ok?: boolean; napcat?: { containerized?: boolean; loginState?: string; qrcode?: { available?: boolean; dataUrl?: string } }; login?: { ready?: boolean; state?: string } } }).body; + const claudeqqHealthBody = (claudeqqHealth as { body?: { ok?: boolean; service?: string; endpoints?: string[]; subscriptions?: { count?: number; enabled?: number }; napcat?: { containerized?: boolean; connected?: boolean; httpConnected?: boolean; wsConnected?: boolean; loginState?: string; qrcode?: { available?: boolean; dataUrl?: string } } } }).body; + const claudeqqNapcatLoginBody = (claudeqqNapcatLogin as { body?: { ok?: boolean; napcat?: { containerized?: boolean; connected?: boolean; httpConnected?: boolean; wsConnected?: boolean; loginState?: string; qrcode?: { available?: boolean; dataUrl?: string } }; login?: { ready?: boolean; state?: string } } }).body; const claudeqqEventsBody = (claudeqqEvents as { body?: { ok?: boolean; events?: unknown[]; count?: number } }).body; const claudeqqSubscriptionsBody = (claudeqqSubscriptions as { body?: { ok?: boolean; subscriptions?: unknown[]; count?: number } }).body; const codeQueueHealthBody = (codeQueueHealth as { body?: { ok?: boolean; queue?: { defaultModel?: string; judgeConfigured?: boolean; modelReasoningEfforts?: Record } } }).body; @@ -972,8 +972,8 @@ async function serviceChecks(config: UniDeskConfig, urls: PublicUrls, checks: E2 addSelectedCheck(checks, options, "microservice:met-nonlinear-projects", (metNonlinearProjects as { ok?: boolean }).ok === true && metNonlinearProjectsBody?.ok === true && Array.isArray(metNonlinearProjectsBody.projects) && metNonlinearProjectsBody.projects.length > 0, metNonlinearProjects); addSelectedCheck(checks, options, "microservice:met-nonlinear-image", (metNonlinearImages as { ok?: boolean }).ok === true && metNonlinearImagesBody?.ok === true && metNonlinearImagesBody.mlImage?.present === true && metNonlinearImagesBody.mlImage?.image === "met-nonlinear-ml:tf26", metNonlinearImages); addSelectedCheck(checks, options, "microservice:claudeqq-status", (claudeqqStatus as { ok?: boolean }).ok === true && (claudeqqStatus as { body?: { microservice?: { id?: string; providerId?: string } } }).body?.microservice?.providerId === "D601", claudeqqStatus); - addSelectedCheck(checks, options, "microservice:claudeqq-health", (claudeqqHealth as { ok?: boolean }).ok === true && claudeqqHealthBody?.ok === true && claudeqqHealthBody.service === "claudeqq" && (claudeqqHealthBody.endpoints ?? []).includes("/api/push/text") && (claudeqqHealthBody.endpoints ?? []).includes("/api/napcat/login"), claudeqqHealth); - addSelectedCheck(checks, options, "microservice:claudeqq-napcat-login", (claudeqqNapcatLogin as { ok?: boolean }).ok === true && claudeqqNapcatLoginBody?.ok === true && claudeqqNapcatLoginBody.napcat?.containerized === true && typeof claudeqqNapcatLoginBody.login?.state === "string" && (claudeqqNapcatLoginBody.login?.ready === true || (claudeqqNapcatLoginBody.napcat?.qrcode?.available === true && String(claudeqqNapcatLoginBody.napcat.qrcode.dataUrl || "").startsWith("data:image/"))), claudeqqNapcatLogin); + addSelectedCheck(checks, options, "microservice:claudeqq-health", (claudeqqHealth as { ok?: boolean }).ok === true && claudeqqHealthBody?.ok === true && claudeqqHealthBody.service === "claudeqq" && (claudeqqHealthBody.endpoints ?? []).includes("/api/push/text") && (claudeqqHealthBody.endpoints ?? []).includes("/api/napcat/login") && claudeqqHealthBody.napcat?.httpConnected === true && claudeqqHealthBody.napcat?.wsConnected === true && claudeqqHealthBody.napcat?.connected === true && claudeqqHealthBody.napcat?.loginState === "logged_in", claudeqqHealth); + addSelectedCheck(checks, options, "microservice:claudeqq-napcat-login", (claudeqqNapcatLogin as { ok?: boolean }).ok === true && claudeqqNapcatLoginBody?.ok === true && claudeqqNapcatLoginBody.napcat?.containerized === true && claudeqqNapcatLoginBody.napcat?.httpConnected === true && claudeqqNapcatLoginBody.napcat?.wsConnected === true && claudeqqNapcatLoginBody.napcat?.connected === true && claudeqqNapcatLoginBody.login?.ready === true && claudeqqNapcatLoginBody.login?.state === "logged_in", claudeqqNapcatLogin); addSelectedCheck(checks, options, "microservice:claudeqq-events", (claudeqqEvents as { ok?: boolean }).ok === true && claudeqqEventsBody?.ok === true && Array.isArray(claudeqqEventsBody.events), claudeqqEvents); addSelectedCheck(checks, options, "microservice:claudeqq-subscriptions", (claudeqqSubscriptions as { ok?: boolean }).ok === true && claudeqqSubscriptionsBody?.ok === true && Array.isArray(claudeqqSubscriptionsBody.subscriptions), claudeqqSubscriptions); addSelectedCheck(checks, options, "microservice:todo-note-status", (todoNoteStatus as { ok?: boolean }).ok === true && (todoNoteStatus as { body?: { microservice?: { id?: string; providerId?: string } } }).body?.microservice?.providerId === config.providerGateway.id, todoNoteStatus); @@ -2459,7 +2459,7 @@ async function frontendCheck(config: UniDeskConfig, urls: PublicUrls, checks: E2 addSelectedCheck(checks, options, "frontend:code-queue-judge-wrap", codexJudgeWrapMetrics.checked === true && codexJudgeWrapMetrics.ok === true, { codexJudgeWrapMetrics }); - addSelectedCheck(checks, options, "frontend:claudeqq-integrated-visible", claudeqqTextLower.includes("claudeqq 工作台") && claudeqqText.includes("D601") && claudeqqText.includes("QQ 事件订阅") && claudeqqText.includes("消息推送") && claudeqqText.includes("事件缓存") && claudeqqText.includes("主用户私聊账号") && claudeqqText.includes("645275593") && claudeqqTextLower.includes("napcat 容器登录") && (claudeqqText.includes("二维码") || claudeqqText.includes("QR SOURCE") || claudeqqText.includes("QR Source") || claudeqqText.includes("已登录")) && claudeqqText.includes("仅 UniDesk frontend 代理访问") && !claudeqqText.includes("{\n"), { claudeqqTextPreview: claudeqqText.slice(0, 1400) }); + addSelectedCheck(checks, options, "frontend:claudeqq-integrated-visible", claudeqqTextLower.includes("claudeqq 工作台") && claudeqqText.includes("D601") && claudeqqText.includes("QQ 事件订阅") && claudeqqText.includes("消息推送") && claudeqqText.includes("事件缓存") && claudeqqText.includes("主用户私聊账号") && claudeqqText.includes("645275593") && claudeqqTextLower.includes("napcat 容器登录") && claudeqqText.includes("已登录") && /health\s+ok/i.test(claudeqqText) && claudeqqText.includes("仅 UniDesk frontend 代理访问") && !claudeqqText.includes("{\n"), { claudeqqTextPreview: claudeqqText.slice(0, 1400) }); addSelectedCheck(checks, options, "frontend:url-route-deeplink", routeInitialPath === "/app/pipeline/" && routeDockerPath === "/nodes/docker/" && routeBackPath === "/app/pipeline/" && routeOverviewPath === "/ops/status/" && routeCodexPath === "/app/code-queue/" && routeDeepLinkText.toLowerCase().includes("pipeline v2 工作台".toLowerCase()) && routeOverviewText.includes("核心指标") && routeCodexShellMetrics.appShell === true && routeCodexShellMetrics.standalone === false && routeCodexShellMetrics.topbar === true && routeCodexShellMetrics.codexPage === true && String(routeCodexShellMetrics.railText || "").includes("用户服务") && String(routeCodexShellMetrics.tabsText || "").includes("Code Queue"), { routeInitialPath, routeDockerPath, routeBackIntermediatePath, routeBackPath, routeOverviewPath, routeCodexPath, routeCodexShellMetrics, routeDeepLinkPreview: routeDeepLinkText.slice(0, 1200), routeOverviewPreview: routeOverviewText.slice(0, 800) }); addSelectedCheck(checks, options, "frontend:pipeline-integrated-visible", pipelineTextLower.includes("pipeline v2 工作台".toLowerCase())