import fs from "fs"; import path from "path"; const BIN_NAME = "studioE5-agent"; // Build the public base URL from an incoming request, respecting common // reverse-proxy headers (X-Forwarded-Proto / X-Forwarded-Host). export function getBaseUrlFromRequest(req: Request): string { const headers = req.headers; const forwardedProto = headers.get("x-forwarded-proto"); const forwardedHost = headers.get("x-forwarded-host"); if (forwardedProto && forwardedHost) { return `${forwardedProto}://${forwardedHost}`; } const url = new URL(req.url); return `${url.protocol}//${url.host}`; } function findVersionFile(): string | null { // Try a few common paths relative to the server workspace and Next.js build output. const candidates = [ path.join(process.cwd(), "..", "agent", "VERSION"), path.join(process.cwd(), "..", "..", "agent", "VERSION"), path.join(process.cwd(), "agent", "VERSION"), path.join(__dirname, "..", "..", "..", "agent", "VERSION"), path.join(__dirname, "..", "..", "agent", "VERSION"), "/app/agent-version", ]; for (const candidate of candidates) { if (fs.existsSync(candidate)) { return candidate; } } return null; } export function getAgentVersion(): string { const versionFile = findVersionFile(); if (versionFile) { return fs.readFileSync(versionFile, "utf-8").trim(); } // Fallback used when the agent workspace is not mounted (should not happen). return "0.3.9"; } export interface AgentDownloadUrls { windows: string; windowsZip: string; linux: string; mac: string; } export function getAgentDownloadUrls( version: string, baseUrl?: string ): AgentDownloadUrls { const prefix = baseUrl ? baseUrl.replace(/\/$/, "") : ""; return { windows: `${prefix}/${BIN_NAME}-v${version}.exe`, windowsZip: `${prefix}/${BIN_NAME}-v${version}-windows.zip`, linux: `${prefix}/${BIN_NAME}-v${version}`, mac: `${prefix}/${BIN_NAME}-v${version}-mac`, }; } export function getAgentVersionInfo(baseUrl?: string) { const version = getAgentVersion(); return { version, downloadUrls: getAgentDownloadUrls(version, baseUrl), }; }