import { Hono } from "hono"; import { getConnInfo } from "@hono/node-server/conninfo"; import { existsSync, readFileSync } from "fs"; import { resolve } from "path"; import type { AccountPool } from "../../auth/account-pool.js"; import { getConfig, getFingerprint } from "../../config.js"; import { getConfigDir, getDataDir, getBinDir, isEmbedded } from "../../paths.js"; import { getTransportInfo } from "../../tls/transport.js"; import { getCurlDiagnostics } from "../../tls/curl-binary.js"; import { isLocalhostRequest } from "../../utils/is-localhost.js"; export function createHealthRoutes(accountPool: AccountPool): Hono { const app = new Hono(); app.get("/health", async (c) => { const authenticated = accountPool.isAuthenticated(); const poolSummary = accountPool.getPoolSummary(); return c.json({ status: "ok", authenticated, pool: { total: poolSummary.total, active: poolSummary.active }, timestamp: new Date().toISOString(), }); }); app.get("/debug/fingerprint", (c) => { const isProduction = process.env.NODE_ENV === "production"; const remoteAddr = getConnInfo(c).remote.address ?? ""; const isLocalhost = isLocalhostRequest(remoteAddr); if (isProduction && !isLocalhost) { c.status(404); return c.json({ error: { message: "Not found", type: "invalid_request_error" } }); } const config = getConfig(); const fp = getFingerprint(); const ua = fp.user_agent_template .replace("{version}", config.client.app_version) .replace("{platform}", config.client.platform) .replace("{arch}", config.client.arch); const promptsDir = resolve(getConfigDir(), "prompts"); const prompts: Record = { "desktop-context.md": existsSync(resolve(promptsDir, "desktop-context.md")), "title-generation.md": existsSync(resolve(promptsDir, "title-generation.md")), "pr-generation.md": existsSync(resolve(promptsDir, "pr-generation.md")), "automation-response.md": existsSync(resolve(promptsDir, "automation-response.md")), }; let updateState = null; const statePath = resolve(getDataDir(), "update-state.json"); if (existsSync(statePath)) { try { updateState = JSON.parse(readFileSync(statePath, "utf-8")); } catch {} } return c.json({ headers: { "User-Agent": ua, originator: config.client.originator, }, client: { app_version: config.client.app_version, build_number: config.client.build_number, platform: config.client.platform, arch: config.client.arch, }, api: { base_url: config.api.base_url, }, model: { default: config.model.default, }, codex_fields: { developer_instructions: "loaded from config/prompts/desktop-context.md", approval_policy: "never", sandbox: "workspace-write", personality: null, ephemeral: null, }, prompts_loaded: prompts, update_state: updateState, }); }); app.get("/debug/diagnostics", (c) => { const remoteAddr = getConnInfo(c).remote.address ?? ""; const isLocalhost = isLocalhostRequest(remoteAddr); if (process.env.NODE_ENV === "production" && !isLocalhost) { c.status(404); return c.json({ error: { message: "Not found", type: "invalid_request_error" } }); } const transport = getTransportInfo(); const curl = getCurlDiagnostics(); const poolSummary = accountPool.getPoolSummary(); const caCertPath = resolve(getBinDir(), "cacert.pem"); return c.json({ transport: { type: transport.type, initialized: transport.initialized, impersonate: transport.impersonate, ffi_error: transport.ffi_error, }, curl: { binary: curl.binary, is_impersonate: curl.is_impersonate, profile: curl.profile, }, proxy: { url: curl.proxy_url }, ca_cert: { found: existsSync(caCertPath), path: caCertPath }, accounts: { total: poolSummary.total, active: poolSummary.active, authenticated: accountPool.isAuthenticated(), }, paths: { bin: getBinDir(), config: getConfigDir(), data: getDataDir(), }, runtime: { platform: process.platform, arch: process.arch, node_version: process.version, embedded: isEmbedded(), }, }); }); return app; }