#!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; import { Agent, fetch as undiciFetch } from 'undici'; function loadEnvFile(filePath) { if (!fs.existsSync(filePath)) return; for (const line of fs.readFileSync(filePath, 'utf8').split('\n')) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith('#')) continue; const idx = trimmed.indexOf('='); if (idx < 0) continue; const key = trimmed.slice(0, idx).trim(); const value = trimmed.slice(idx + 1).trim(); if (!process.env[key]) process.env[key] = value; } } loadEnvFile(path.join(process.cwd(), '.env')); const insecureDispatcher = new Agent({ connect: { rejectUnauthorized: false } }); const publicBase = (process.env.H5_PUBLIC_BASE_URL || 'https://m.tkmind.cn').replace(/\/$/, ''); const targets = (process.env.TKMIND_API_TARGETS || process.env.TKMIND_API_TARGET || '') .split(',') .map((value) => value.trim()) .filter(Boolean); async function fetchText(url, init = {}) { const res = await undiciFetch(url, { ...init, dispatcher: url.startsWith('https://127.0.0.1') ? insecureDispatcher : undefined, }); const text = await res.text(); return { res, text }; } async function checkJson(pathname) { const { res, text } = await fetchText(`${publicBase}${pathname}`); let json = null; try { json = JSON.parse(text); } catch { json = null; } return { ok: res.ok, status: res.status, json, text: json ? undefined : text.slice(0, 160) }; } async function checkSseHeaders(pathname) { const { res } = await fetchText(`${publicBase}${pathname}`, { method: 'HEAD', headers: { Accept: 'text/event-stream' }, }); return { ok: res.status === 401 || res.ok, status: res.status, xAccelBuffering: res.headers.get('x-accel-buffering'), contentType: res.headers.get('content-type'), cacheControl: res.headers.get('cache-control'), }; } async function checkTarget(target) { const { res, text } = await fetchText(new URL('/status', target).toString()); return { target, ok: res.ok, status: res.status, text: text.slice(0, 80) }; } const result = { ok: true, publicBase, checkedAt: new Date().toISOString(), status: await checkJson('/api/status').catch((err) => ({ ok: false, error: err.message })), runtime: await checkJson('/api/runtime/status').catch((err) => ({ ok: false, error: err.message })), sse: { sessions: await checkSseHeaders('/api/sessions/check-stream-runtime/events').catch((err) => ({ ok: false, error: err.message, })), agentRuns: await checkSseHeaders('/api/agent/runs/check-stream-runtime/events').catch((err) => ({ ok: false, error: err.message, })), }, targets: await Promise.all(targets.map((target) => checkTarget(target).catch((err) => ({ target, ok: false, error: err.message, })))), }; result.ok = Boolean( result.status.ok && result.runtime.ok && result.sse.sessions.ok && result.sse.agentRuns.ok && result.targets.every((target) => target.ok), ); console.log(JSON.stringify(result, null, 2)); process.exit(result.ok ? 0 : 1);