(port: number, apiKey?: string)
| 927 | * @param apiKey - Optional API key for cloud storage mode |
| 928 | */ |
| 929 | export function startHttpServer(port: number, apiKey?: string): void { |
| 930 | // Set cloud mode if API key provided |
| 931 | if (apiKey) { |
| 932 | setCloudApiKey(apiKey); |
| 933 | } |
| 934 | |
| 935 | const server = createServer(async (req, res) => { |
| 936 | const url = new URL(req.url || "/", `http://localhost:${port}`); |
| 937 | const pathname = url.pathname; |
| 938 | const method = req.method || "GET"; |
| 939 | |
| 940 | // Log all requests for debugging |
| 941 | if (method !== "OPTIONS" && pathname !== "/health") { |
| 942 | log(`[HTTP] ${method} ${pathname}`); |
| 943 | } |
| 944 | |
| 945 | // Handle CORS preflight |
| 946 | if (method === "OPTIONS") { |
| 947 | return handleCors(res); |
| 948 | } |
| 949 | |
| 950 | // Health check (always local) |
| 951 | if (pathname === "/health" && method === "GET") { |
| 952 | return sendJson(res, 200, { status: "ok", mode: isCloudMode() ? "cloud" : "local" }); |
| 953 | } |
| 954 | |
| 955 | // Status endpoint (always local) |
| 956 | if (pathname === "/status" && method === "GET") { |
| 957 | const webhookUrls = getWebhookUrls(); |
| 958 | return sendJson(res, 200, { |
| 959 | mode: isCloudMode() ? "cloud" : "local", |
| 960 | webhooksConfigured: webhookUrls.length > 0, |
| 961 | webhookCount: webhookUrls.length, |
| 962 | activeListeners: sseConnections.size, |
| 963 | agentListeners: agentConnections.size, |
| 964 | }); |
| 965 | } |
| 966 | |
| 967 | // MCP protocol endpoint (always local - allows Claude Code to connect) |
| 968 | if (pathname === "/mcp") { |
| 969 | return handleMcp(req, res); |
| 970 | } |
| 971 | |
| 972 | // Cloud mode: proxy all other requests to cloud API |
| 973 | if (isCloudMode()) { |
| 974 | return proxyToCloud(req, res, pathname + url.search); |
| 975 | } |
| 976 | |
| 977 | // Local mode: use local store |
| 978 | const match = matchRoute(method, pathname); |
| 979 | if (!match) { |
| 980 | return sendError(res, 404, "Not found"); |
| 981 | } |
| 982 | |
| 983 | try { |
| 984 | await match.handler(req, res, match.params); |
| 985 | } catch (err) { |
| 986 | console.error("Request error:", err); |
no test coverage detected
searching dependent graphs…