@codeproxy/cli 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  'use strict';
2
3
 
3
4
  var fs = require('fs');
@@ -769,7 +770,7 @@ Received ${signal}, shutting down...`);
769
770
  process.on("SIGINT", () => void shutdown("SIGINT"));
770
771
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
771
772
  }
772
- if (process.argv[1]?.endsWith("cli.js") || process.argv[1]?.endsWith("cli.ts")) {
773
+ if (process.argv[1]?.endsWith("cli.js") || process.argv[1]?.endsWith("cli.ts") || process.argv[1]?.endsWith("codeproxy")) {
773
774
  void main();
774
775
  }
775
776
 
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/proxy.ts","../src/utils/config.ts","../src/server/cli.ts"],"names":["createResponsesFetch","http","resolve","Readable","mkdirSync","join","writeFileSync","existsSync","readFileSync"],"mappings":"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","file":"cli.cjs","sourcesContent":["// ==============================================================================\n// Helpers\n// ==============================================================================\n\n/**\n * Local HTTP proxy that exposes the Responses API and forwards translated\n * requests to the configured upstream API format.\n */\n\nimport http, { type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport { Readable } from 'node:stream';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\n// ==============================================================================\n// Helpers\n// ==============================================================================\nexport function fmtTime(date: Date): string {\n return date.toLocaleTimeString('en-US', { hour12: false });\n}\n\nexport function fmtDuration(ms: number): string {\n // ==============================================================================\n // Server\n // ==============================================================================\n\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\nimport { createResponsesFetch, type CreateResponsesFetchOptions } from '@codeproxy/core';\n\nexport interface StartProxyOptions extends Omit<CreateResponsesFetchOptions, 'passthroughFetch'> {\n /** Host to bind to. Defaults to `127.0.0.1`. */\n host?: string;\n /** Port to listen on. Defaults to `8787`; pass `0` for a random free port. */\n port?: number;\n /** Enable permissive CORS (useful for local browser dev). Defaults to true. */\n cors?: boolean;\n /** Optional logger. Defaults to `console`. Pass `null` to silence. */\n logger?: Pick<Console, 'log' | 'warn' | 'error'> | null;\n /** Optional callback to receive cache statistics after each request completes. */\n onCacheStats?: (stats: {\n cachedTokens: number;\n cacheCreationTokens: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n method?: string;\n url?: string;\n durationMs?: number;\n }) => void;\n}\n\nexport interface RunningProxy {\n host: string;\n port: number;\n url: string;\n server: Server;\n close: () => Promise<void>;\n}\n\nexport async function startProxy(options: StartProxyOptions): Promise<RunningProxy> {\n const host = options.host ?? '127.0.0.1';\n const port = options.port ?? 8787;\n const cors = options.cors ?? true;\n const logger = options.logger === null ? null : (options.logger ?? console);\n\n // Rolling average for request duration coloring (last 50 requests)\n const durationHistory: number[] = [];\n function updateRollingAverage(ms: number) {\n durationHistory.push(ms); /* c8 ignore next 3 -- threshold rarely hit */\n if (durationHistory.length > 50) {\n durationHistory.shift();\n }\n return durationHistory.reduce((sum, val) => sum + val, 0) / durationHistory.length;\n }\n\n // Centralized status line for all active requests\n const activeRequests = new Map<string, { method: string; url: string; startTime: number }>();\n // ==============================================================================\n // Request Handler\n // ==============================================================================\n\n let statusTimerId: ReturnType<typeof setInterval> | null = null;\n\n function drawStatusLine() {\n if (activeRequests.size === 0) {\n return; /* c8 ignore next -- empty guard */\n }\n const parts = Array.from(activeRequests.entries()).map(([, req]) => {\n const elapsed = Date.now() - req.startTime;\n return `[${fmtDuration(elapsed)}]`;\n });\n process.stdout.write(`\\r\\x1b[K⏳ ${parts.join(', ')}`);\n }\n\n const requestTracker = {\n add(method: string, url: string): string {\n const id = `${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;\n activeRequests.set(id, { method, url, startTime: Date.now() });\n drawStatusLine();\n if (!statusTimerId) {\n statusTimerId = setInterval(drawStatusLine, 150);\n }\n return id;\n },\n remove(id: string) {\n activeRequests.delete(id);\n if (activeRequests.size === 0) {\n process.stdout.write('\\r\\x1b[K');\n if (statusTimerId) {\n clearInterval(statusTimerId);\n statusTimerId = null;\n }\n }\n },\n };\n\n const requestInfo = { method: '', url: '', startTime: 0, resultLog: '' };\n\n const upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n } = {};\n\n const baseFetch = options.fetch ?? globalThis.fetch;\n const capturingFetch: typeof fetch = async (input, init) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? input?.method ?? 'GET').toUpperCase();\n const reqHeaders = headersInitToObject(init?.headers);\n let reqBody: unknown = undefined;\n if (init?.body != null) {\n if (typeof init.body === 'string') {\n reqBody = tryParseJson(init.body);\n } /* c8 ignore next 6 -- defensive body serialization */ else if (\n init.body instanceof ArrayBuffer\n ) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else if (ArrayBuffer.isView(init.body)) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else {\n reqBody = String(init.body);\n }\n }\n upstreamCapture.request = { url, method, headers: reqHeaders, body: reqBody };\n\n const resp = await baseFetch(input, init);\n\n if (!resp.ok) {\n const clone = resp.clone();\n const text = await clone.text().catch(() => '');\n upstreamCapture.response = {\n status: resp.status,\n statusText: resp.statusText,\n headers: headersToObject(resp.headers),\n body: tryParseJson(text),\n };\n } else {\n upstreamCapture.response = undefined;\n }\n return resp;\n };\n\n const apiFetch = createResponsesFetch({\n upstreamFormat: options.upstreamFormat,\n baseUrl: options.baseUrl,\n apiVersion: options.apiVersion,\n model: options.model,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n dropImages: options.dropImages,\n fallbackUpstream: options.fallbackUpstream,\n fetch: capturingFetch,\n passthroughFetch: async () =>\n new Response(JSON.stringify({ error: { message: 'Not found' } }), {\n status: 404,\n headers: { 'content-type': 'application/json' },\n }),\n onCacheStats: (stats) => {\n const durationMs = requestInfo.startTime ? Date.now() - requestInfo.startTime : 0;\n const billedTokens = stats.inputTokens + stats.outputTokens - stats.cachedTokens;\n const parts = [\n `total=${stats.totalTokens}`,\n `input=${stats.inputTokens}`,\n `output=${stats.outputTokens}`,\n `cached=${stats.cachedTokens}`,\n `billed=${billedTokens}`,\n ];\n if (stats.cacheCreationTokens > 0) {\n parts.push(`cache_creation=${stats.cacheCreationTokens}`);\n }\n const avg = updateRollingAverage(durationMs);\n const ratio = avg > 0 ? durationMs / avg : 1;\n const color = ratio < 0.8 ? '\\x1b[32m' : ratio < 1.5 ? '\\x1b[33m' : '\\x1b[31m';\n const reset = '\\x1b[0m';\n const logMsg = `[${fmtTime(new Date())}] -> 200 (${color}${fmtDuration(durationMs)}${reset} avg=${fmtDuration(Math.round(avg))}) [${parts.join(', ')}]`;\n requestInfo.resultLog =\n stats.cachedTokens < 1024 && billedTokens > 0 ? `⚠️ NO CACHE -- ${logMsg}` : logMsg;\n\n if (options.onCacheStats) {\n options.onCacheStats({\n ...stats,\n method: requestInfo.method || undefined,\n url: requestInfo.url || undefined,\n durationMs: durationMs || undefined,\n });\n }\n },\n });\n\n const server = http.createServer(async (req, res) => {\n const start = Date.now();\n requestInfo.method = req.method ?? 'POST';\n requestInfo.url = req.url ?? '/v1/responses';\n requestInfo.startTime = start;\n\n const abortController = new AbortController();\n const timeoutMs = options.timeoutMs;\n let timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n if (timeoutMs && timeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n logger?.warn(`[timeout] request exceeded ${timeoutMs}ms, aborting`);\n abortController.abort();\n res.destroy();\n req.destroy();\n }, timeoutMs);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await handleRequest(req, res, {\n apiFetch,\n cors,\n logger,\n method: req.method ?? 'POST',\n url: req.url ?? '/',\n upstreamCapture,\n requestInfo,\n requestTracker,\n signal: abortController.signal,\n });\n } catch (err) {\n logger?.error('[proxy-error]', err);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: 'Internal server error' } }));\n }\n /* c8 ignore start */\n } catch {\n // ignore\n } /* c8 ignore stop */\n } finally {\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n }\n }\n });\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n const actualPort = (() => {\n // eslint-disable-next-line no-restricted-syntax -- net.Server.address() returns string | AddressInfo | null\n const addr = server.address() as { port: number } | null;\n return addr.port;\n })();\n const url = `http://${host}:${actualPort}`;\n logger?.log(`Proxy listening on ${url}`);\n logger?.log(`Upstream format: ${options.upstreamFormat}`);\n logger?.log(`Upstream URL: ${options.baseUrl}`);\n resolve({\n host,\n port: actualPort,\n url,\n server,\n close: () =>\n new Promise((res) => {\n server.close((err) => {\n /* c8 ignore start */\n if (err) {\n logger?.warn('Error closing server:', err);\n }\n /* c8 ignore stop */\n res();\n });\n }),\n });\n });\n server.once('error', reject);\n });\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n opts: {\n apiFetch: typeof fetch;\n cors: boolean;\n logger: Pick<Console, 'log' | 'warn' | 'error'> | null;\n method: string;\n url: string;\n upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n };\n requestInfo: { resultLog: string };\n requestTracker: { add: (method: string, url: string) => string; remove: (id: string) => void };\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (opts.cors) {\n setCorsHeaders(res);\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const method = req.method ?? 'GET';\n const urlPath = req.url ?? '/';\n const headers = flattenIncomingHeaders(req.headers);\n\n let body: Buffer | undefined;\n if (method !== 'GET' && method !== 'HEAD') {\n body = await readIncomingBody(req);\n }\n\n if (!/^\\/v1\\/responses\\/?(?:\\?|$)/.test(urlPath)) {\n res.writeHead(404, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: `Not found: ${method} ${urlPath}` } }));\n return;\n }\n\n const requestBodyText = body ? body.toString('utf8') : undefined;\n\n const requestStart = Date.now();\n const requestId = opts.requestTracker.add(method, urlPath);\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const response = await opts.apiFetch(`http://local${urlPath}`, {\n method,\n headers,\n body: body ? new Uint8Array(body) : undefined,\n signal: opts.signal,\n });\n\n // Consume response body so onCacheStats fires (for streaming responses)\n const responseBodyText = response.body ? await response.clone().text() : '';\n\n // Remove from active requests and write final result\n opts.requestTracker.remove(requestId);\n /* c8 ignore start */\n if (opts.logger) {\n if (response.status >= 400) {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n } else if (opts.requestInfo.resultLog) {\n process.stdout.write(`\\r\\x1b[K${opts.requestInfo.resultLog}\\n`);\n } else {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n }\n }\n /* c8 ignore stop */\n if (response.status >= 400) {\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const filePath = saveErrorDump({\n method: opts.method,\n url: opts.url,\n clientRequest: {\n headers,\n body: tryParseJson(requestBodyText ?? ''),\n },\n upstreamRequest: opts.upstreamCapture.request,\n upstreamResponse: opts.upstreamCapture.response,\n proxyResponse: {\n status: response.status,\n headers: headersToObject(response.headers),\n body: tryParseJson(responseBodyText),\n },\n });\n opts.logger?.error(`[proxy-failure] full exchange saved to ${filePath}`);\n } catch (dumpErr) {\n opts.logger?.error('[proxy-failure] failed to persist error dump', dumpErr);\n }\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n if (opts.cors) {\n Object.assign(outHeaders, corsHeaders());\n }\n\n res.writeHead(response.status, outHeaders);\n\n /* c8 ignore next 3 */\n if (!response.body) {\n res.end();\n return;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- fetch response.body is not typed as node stream\n const typedBody = response.body! as unknown as import('stream/web').ReadableStream<Uint8Array>;\n const nodeStream = Readable.fromWeb(typedBody);\n nodeStream.pipe(res);\n await new Promise<void>((resolve, reject) => {\n nodeStream.once('end', resolve);\n nodeStream.once('error', reject);\n res.once('close', resolve);\n });\n } catch (err) {\n opts.requestTracker.remove(requestId);\n throw err;\n }\n}\n\nfunction readIncomingBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => {\n const buf: Buffer = chunk;\n chunks.push(buf);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nexport function flattenIncomingHeaders(\n headers: IncomingMessage['headers'],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value == null) {\n continue;\n }\n out[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : String(value);\n }\n return out;\n}\n\nexport function headersToObject(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nfunction setCorsHeaders(res: ServerResponse): void {\n const headers = corsHeaders();\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n}\n\nexport function corsHeaders(): Record<string, string> {\n return {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET,POST,OPTIONS',\n 'access-control-allow-headers':\n 'authorization,content-type,x-api-key,anthropic-version,anthropic-beta,anthropic-dangerous-direct-browser-access',\n 'access-control-expose-headers': 'content-type',\n };\n}\n\nexport function tryParseJson(str: string | undefined | null): unknown {\n if (!str) {\n return str ?? null;\n }\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n\nexport function headersInitToObject(headersInit: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!headersInit) {\n return out;\n }\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n out[String(key).toLowerCase()] = String(value);\n }\n return out;\n }\n for (const [key, value] of Object.entries(headersInit)) {\n out[key.toLowerCase()] = String(value);\n }\n return out;\n}\n\nexport function saveErrorDump(dump: {\n method: string;\n url: string;\n clientRequest: { headers: Record<string, string>; body: unknown };\n upstreamRequest?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n upstreamResponse?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n proxyResponse: { status: number; headers: Record<string, string>; body: unknown };\n}): string {\n const dir = resolve(process.cwd(), 'logs');\n mkdirSync(dir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n const status = dump.upstreamResponse?.status ?? dump.proxyResponse.status;\n const filename = `proxy-error-${ts}-${status}.json`;\n const filePath = join(dir, filename);\n const payload = {\n timestamp: new Date().toISOString(),\n ...dump,\n };\n redactAuth(payload.clientRequest?.headers);\n redactAuth(payload.upstreamRequest?.headers);\n writeFileSync(filePath, JSON.stringify(payload, null, 2));\n return filePath;\n}\n\nexport function redactAuth(headers: Record<string, string> | undefined): void {\n if (!headers) {\n return;\n }\n for (const key of Object.keys(headers)) {\n const lowerKey = key.toLowerCase();\n if (\n lowerKey === 'authorization' ||\n lowerKey === 'x-api-key' ||\n lowerKey === 'api-key' ||\n lowerKey === 'cookie'\n ) {\n headers[key] = '[REDACTED]';\n }\n }\n}\n","// ==============================================================================\n// Config Loader\n// ==============================================================================\n/**\n * Configuration file loader and validator.\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n\nconst CONFIG_FILE_NAMES = [\n 'codeproxy.config.json',\n 'codeproxy.config.js',\n 'codeproxy.config.mjs',\n 'codeproxy.config.ts',\n '.codeproxy.json',\n '.codeproxy.js',\n] as const;\n\n/**\n * Find and load a config file.\n */\nexport async function loadConfigFile(\n searchFrom: string = process.cwd(),\n): Promise<ConfigFile | null> {\n const configPath = findConfigPath(searchFrom);\n if (!configPath) {\n return null;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (configPath.endsWith('.json')) {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } else if (configPath.endsWith('.js') || configPath.endsWith('.mjs')) {\n /* c8 ignore start */\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } else if (configPath.endsWith('.ts')) {\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } /* c8 ignore stop */\n return null; /* c8 ignore next -- trailing fallback */\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n return null;\n }\n}\n\nfunction findConfigPath(searchFrom: string): string | null {\n let currentDir = searchFrom;\n const root = parseRoot(searchFrom);\n\n while (currentDir !== root && currentDir !== dirname(currentDir)) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = resolve(currentDir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n currentDir = dirname(currentDir);\n }\n\n return null;\n}\n\nfunction parseRoot(path: string): string {\n const parsed = resolve(path);\n const root = parsed.split(/[\\\\/]/)[0];\n return resolve(root);\n}\n\n/**\n * Validate the config file structure.\n */\nexport function validateConfig(config: unknown): { valid: boolean; error?: string } {\n if (typeof config !== 'object' || config === null) {\n return { valid: false, error: 'Config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = config as Record<string, unknown>;\n\n if (typeof cfg.version !== 'string') {\n return { valid: false, error: 'Config must have a version string' };\n }\n\n if (typeof cfg.currentUpstream !== 'string') {\n return { valid: false, error: 'Config must have a currentUpstream string' };\n }\n\n if (typeof cfg.upstreams !== 'object' || cfg.upstreams === null) {\n return { valid: false, error: 'Config must have an upstreams object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const upstreams: Record<string, unknown> = cfg.upstreams as Record<string, unknown>;\n\n if (!(cfg.currentUpstream in upstreams)) {\n return {\n valid: false,\n error: `currentUpstream \"${cfg.currentUpstream}\" not found in upstreams`,\n };\n }\n\n for (const [name, upstream] of Object.entries(upstreams)) {\n const result = validateUpstreamConfig(upstream);\n if (!result.valid) {\n return {\n valid: false,\n error: `Upstream \"${name}\" is invalid: ${result.error}`,\n };\n }\n }\n\n return { valid: true };\n}\n\nexport function validateUpstreamConfig(upstream: unknown): {\n valid: boolean;\n error?: string;\n} {\n if (typeof upstream !== 'object' || upstream === null) {\n return { valid: false, error: 'Upstream config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = upstream as Record<string, unknown>;\n\n if (cfg.format !== undefined) {\n if (typeof cfg.format !== 'string') {\n return { valid: false, error: 'format must be a string if provided' };\n }\n const validFormats = ['anthropic', 'openai-chat'];\n if (!validFormats.includes(cfg.format)) {\n return {\n valid: false,\n error: `Invalid format: ${cfg.format}. Must be one of: ${validFormats.join(', ')}`,\n };\n }\n }\n\n if (typeof cfg.baseUrl !== 'string') {\n return { valid: false, error: 'baseUrl is required and must be a string' };\n }\n\n if (cfg.apiVersion !== undefined && typeof cfg.apiVersion !== 'string') {\n return { valid: false, error: 'apiVersion must be a string if provided' };\n }\n\n if (cfg.apiKey !== undefined && typeof cfg.apiKey !== 'string') {\n return { valid: false, error: 'apiKey must be a string if provided' };\n }\n\n if (cfg.model !== undefined && typeof cfg.model !== 'string') {\n return { valid: false, error: 'model must be a string if provided' };\n }\n\n if (cfg.dropImages !== undefined && typeof cfg.dropImages !== 'boolean') {\n return { valid: false, error: 'dropImages must be a boolean if provided' };\n }\n\n if (cfg.fallback !== undefined && typeof cfg.fallback !== 'string') {\n return { valid: false, error: 'fallback must be a string if provided' };\n }\n\n if (cfg.headers !== undefined && (typeof cfg.headers !== 'object' || cfg.headers === null)) {\n return { valid: false, error: 'headers must be an object if provided' };\n }\n\n if (cfg.reasoningEffort !== undefined && typeof cfg.reasoningEffort !== 'string') {\n return { valid: false, error: 'reasoningEffort must be a string if provided' };\n }\n\n // thinking is optional and can be any type; no validation needed\n\n return { valid: true };\n}\n\n/**\n * Get the current upstream config from a validated config file.\n */\nexport function getCurrentUpstreamConfig(config: ConfigFile): UpstreamConfig | null {\n const upstream = config.upstreams[config.currentUpstream];\n if (!upstream) {\n return null;\n }\n return upstream;\n}\n\n// Re-export types\nexport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n","// ==============================================================================\n// Server Startup\n// ==============================================================================\n\n/**\n * `codeproxy` CLI.\n *\n * Usage:\n * npx codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n * npx codeproxy --config config.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { startProxy, type StartProxyOptions } from './proxy.js';\nimport type { UpstreamFormat } from '@codeproxy/core';\nimport { validateConfig, getCurrentUpstreamConfig, type ConfigFile } from '../utils/config.js';\n\ninterface CliArgs {\n upstreamFormat?: UpstreamFormat | string;\n config?: string;\n host?: string;\n port?: number;\n baseUrl?: string;\n apiVersion?: string;\n apikey?: string;\n model?: string;\n cors?: boolean;\n dropImages?: boolean;\n help?: boolean;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n const out: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n const take = () => argv[++i];\n switch (arg) {\n case '-h':\n case '--help':\n out.help = true;\n break;\n case '-p':\n case '--port':\n out.port = Number(take());\n break;\n case '--host':\n out.host = take();\n break;\n case '--upstream-format':\n out.upstreamFormat = take();\n break;\n case '--base-url':\n out.baseUrl = take();\n break;\n case '--config':\n out.config = take();\n break;\n case '--api-version':\n out.apiVersion = take();\n break;\n case '--apikey':\n out.apikey = take();\n break;\n case '--model':\n out.model = take();\n break;\n case '--drop-images':\n out.dropImages = true;\n break;\n case '--no-cors':\n out.cors = false;\n break;\n default:\n if (arg.startsWith('--upstream-format=')) {\n out.upstreamFormat = arg.slice('--upstream-format='.length);\n } else if (arg.startsWith('--port=')) {\n out.port = Number(arg.slice('--port='.length));\n } else if (arg.startsWith('--host=')) {\n out.host = arg.slice('--host='.length);\n } else if (arg.startsWith('--base-url=')) {\n out.baseUrl = arg.slice('--base-url='.length);\n } else if (arg.startsWith('--api-version=')) {\n out.apiVersion = arg.slice('--api-version='.length);\n } else if (arg.startsWith('--apikey=')) {\n out.apikey = arg.slice('--apikey='.length);\n } else if (arg.startsWith('--model=')) {\n out.model = arg.slice('--model='.length);\n } else if (arg.startsWith('--config=')) {\n out.config = arg.slice('--config='.length);\n } else {\n console.error(`Unknown argument: ${arg}`);\n out.help = true;\n }\n }\n }\n return out;\n}\n\nexport function printHelp(): void {\n console.log(`codeproxy - local Responses API proxy\n\nUsage:\n codeproxy --base-url <url> [options]\n codeproxy --config <file> [options]\n\nOptions:\n --base-url <url> Upstream endpoint URL (required when not using --config)\n --upstream-format <fmt> Upstream API format: anthropic | openai-chat\n (optional; inferred from --base-url when omitted:\n */messages or *anthropic* → anthropic,\n */chat/completions → openai-chat)\n --config <file> Use a config file instead of CLI flags\n --host <host> Bind host (default: 127.0.0.1)\n -p, --port <port> Bind port (default: 8787; 0 = random)\n --api-version <ver> Override anthropic-version header (anthropic only)\n --apikey <key> Override upstream Authorization: Bearer <key>\n --model <name> Override the model field in incoming requests\n --no-cors Disable CORS headers\n -h, --help Show help\n\nConfig File Mode:\n When using --config, upstream settings are loaded from the config file.\n Command-line options can override config values.\n\n Config file format (JSON):\n {\n \"version\": \"1.0\",\n \"currentUpstream\": \"my-claude\",\n \"upstreams\": {\n \"my-claude\": {\n \"baseUrl\": \"https://api.anthropic.com/v1/messages\",\n \"apiKey\": \"your-api-key\",\n \"model\": \"claude-sonnet-4-5\"\n },\n \"my-openai\": {\n \"baseUrl\": \"https://api.openai.com/v1/chat/completions\",\n \"apiKey\": \"your-openai-key\"\n }\n }\n }\n\n \"format\" is optional; inferred from baseUrl when omitted.\n\nAuth is caller-driven: send Authorization: Bearer <key> (or the upstream's\nnative header) when calling the proxy. Nothing is stored server-side.\n\nExamples:\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n codeproxy --upstream-format openai-chat --base-url https://api.openai.com/v1/chat/completions\n codeproxy --config my-config.json\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages --apikey <key>\n`);\n}\n\nexport async function loadConfigFile(configPath: string): Promise<ConfigFile> {\n if (!existsSync(configPath)) {\n console.error(`Config file not found: ${configPath}`);\n process.exit(1);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n process.exit(1);\n }\n}\n\nexport async function loadConfigAndApplyOverrides(\n configPath: string,\n overrides: CliArgs,\n): Promise<StartProxyOptions> {\n const config = await loadConfigFile(configPath);\n\n const validation = validateConfig(config);\n if (!validation.valid) {\n console.error(`Invalid config file: ${validation.error}`);\n process.exit(1);\n }\n\n const upstreamConfig = getCurrentUpstreamConfig(config);\n /* c8 ignore start */ if (!upstreamConfig) {\n console.error(`Current upstream \"${config.currentUpstream}\" not found in config`);\n process.exit(1);\n } /* c8 ignore stop */\n\n console.log(`Loaded config from: ${configPath}`);\n console.log(\n `Current upstream: ${config.currentUpstream}${upstreamConfig.format ? ` (${upstreamConfig.format})` : ''}`,\n );\n console.log(`Model: ${upstreamConfig.model || '(not set)'}`);\n const mergedEffort = upstreamConfig.reasoningEffort ?? config.reasoningEffort;\n if (mergedEffort) {\n console.log(`Reasoning effort: ${mergedEffort}`);\n }\n const mergedHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(mergedHeaders, upstreamConfig.headers);\n }\n if (mergedHeaders.authorization) {\n mergedHeaders.authorization = '\"[REDACTED]\"';\n }\n if (Object.keys(mergedHeaders).length > 0) {\n console.log(`Headers: ${JSON.stringify(mergedHeaders)}`);\n }\n // ==============================================================================\n // Proxy Launch\n // ==============================================================================\n\n const options: StartProxyOptions = {\n upstreamFormat: upstreamConfig.format,\n baseUrl: overrides.baseUrl || upstreamConfig.baseUrl,\n apiVersion: overrides.apiVersion || upstreamConfig.apiVersion,\n model: overrides.model || upstreamConfig.model,\n host: overrides.host || upstreamConfig.host,\n port:\n overrides.port !== undefined\n ? overrides.port\n : // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n (config as unknown as Record<string, unknown>).port\n ? // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n Number((config as unknown as Record<string, unknown>).port)\n : upstreamConfig.port\n ? Number(upstreamConfig.port)\n : undefined,\n timeoutMs: upstreamConfig.timeoutMs ?? config.timeoutMs,\n dropImages: upstreamConfig.dropImages,\n cors: overrides.cors,\n reasoning_effort: upstreamConfig.reasoningEffort ?? config.reasoningEffort,\n thinking: upstreamConfig.thinking ?? config.thinking,\n };\n\n const defaultHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(defaultHeaders, upstreamConfig.headers);\n }\n if (upstreamConfig.apiKey) {\n defaultHeaders.authorization = `Bearer ${upstreamConfig.apiKey}`;\n }\n if (overrides.apikey) {\n defaultHeaders.authorization = `Bearer ${overrides.apikey}`;\n }\n\n if (Object.keys(defaultHeaders).length > 0) {\n options.defaultHeaders = defaultHeaders;\n }\n\n // Resolve fallback upstream if configured\n if (upstreamConfig.fallback) {\n const fbConfig = config.upstreams[upstreamConfig.fallback];\n if (fbConfig) {\n const fbHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (fbConfig.headers) {\n Object.assign(fbHeaders, fbConfig.headers);\n }\n if (fbConfig.apiKey) {\n fbHeaders.authorization = `Bearer ${fbConfig.apiKey}`;\n }\n const fbFormat: UpstreamFormat | undefined = fbConfig.format;\n options.fallbackUpstream = {\n baseUrl: fbConfig.baseUrl,\n upstreamFormat: fbFormat,\n model: fbConfig.model ?? options.model,\n defaultHeaders: Object.keys(fbHeaders).length > 0 ? fbHeaders : undefined,\n apiVersion: fbConfig.apiVersion ?? options.apiVersion,\n reasoning_effort: fbConfig.reasoningEffort ?? options.reasoning_effort,\n thinking: fbConfig.thinking ?? options.thinking,\n };\n console.log(\n `Fallback upstream: ${upstreamConfig.fallback}${fbConfig.model ? ` (${fbConfig.model})` : ''}`,\n );\n } else {\n console.warn(`Warning: fallback upstream \"${upstreamConfig.fallback}\" not found in config`);\n }\n }\n\n return options;\n}\n\n/* c8 ignore next -- main is entry point */\nexport async function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n\n if (args.help) {\n printHelp();\n process.exit(0);\n }\n\n let options: StartProxyOptions;\n\n if (args.config) {\n options = await loadConfigAndApplyOverrides(args.config, args);\n } else if (args.baseUrl) {\n // eslint-disable-next-line no-restricted-syntax -- parsed string may not match union type\n const upstreamFormat = args.upstreamFormat as UpstreamFormat | undefined;\n options = {\n upstreamFormat,\n baseUrl: args.baseUrl,\n host: args.host,\n port: args.port,\n apiVersion: args.apiVersion,\n model: args.model,\n defaultHeaders: args.apikey ? { authorization: `Bearer ${args.apikey}` } : undefined,\n dropImages: args.dropImages,\n cors: args.cors,\n };\n } else {\n console.error('Error: Either --config <file> or --base-url <url> is required');\n console.error('');\n printHelp();\n process.exit(1);\n }\n\n const proxy = await startProxy(options);\n /* c8 ignore start */\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await proxy.close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n /* c8 ignore stop */\n}\n\n/* c8 ignore start */\nif (process.argv[1]?.endsWith('cli.js') || process.argv[1]?.endsWith('cli.ts')) {\n void main();\n}\n/* c8 ignore stop */\n"]}
1
+ {"version":3,"sources":["../src/server/proxy.ts","../src/utils/config.ts","../src/server/cli.ts"],"names":["createResponsesFetch","http","resolve","Readable","mkdirSync","join","writeFileSync","existsSync","readFileSync"],"mappings":";;;;;;;;;;;;;AAiBO,SAAS,QAAQ,IAAA,EAAoB;AAC1C,EAAA,OAAO,KAAK,kBAAA,CAAmB,OAAA,EAAS,EAAE,MAAA,EAAQ,OAAO,CAAA;AAC3D;AAEO,SAAS,YAAY,EAAA,EAAoB;AAK9C,EAAA,IAAI,KAAK,GAAA,EAAM;AACb,IAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA,EAAA,CAAA;AAAA,EAC1B;AACA,EAAA,IAAI,KAAK,GAAA,EAAO;AACd,IAAA,OAAO,CAAA,EAAA,CAAI,EAAA,GAAK,GAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,EAClC;AACA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,GAAK,CAAA;AACrC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAO,EAAA,GAAK,MAAS,GAAI,CAAA;AAC9C,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AACvD;AAiCA,eAAsB,WAAW,OAAA,EAAmD;AAClF,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,WAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,IAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,IAAA;AAC7B,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA,KAAW,IAAA,GAAO,IAAA,GAAQ,QAAQ,MAAA,IAAU,OAAA;AAGnE,EAAA,MAAM,kBAA4B,EAAC;AACnC,EAAA,SAAS,qBAAqB,EAAA,EAAY;AACxC,IAAA,eAAA,CAAgB,KAAK,EAAE,CAAA;AACvB,IAAA,IAAI,eAAA,CAAgB,SAAS,EAAA,EAAI;AAC/B,MAAA,eAAA,CAAgB,KAAA,EAAM;AAAA,IACxB;AACA,IAAA,OAAO,eAAA,CAAgB,OAAO,CAAC,GAAA,EAAK,QAAQ,GAAA,GAAM,GAAA,EAAK,CAAC,CAAA,GAAI,eAAA,CAAgB,MAAA;AAAA,EAC9E;AAGA,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAgE;AAK3F,EAAA,IAAI,aAAA,GAAuD,IAAA;AAE3D,EAAA,SAAS,cAAA,GAAiB;AACxB,IAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,GAAG,GAAG,CAAA,KAAM;AAClE,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,GAAA,CAAI,SAAA;AACjC,MAAA,OAAO,CAAA,CAAA,EAAI,WAAA,CAAY,OAAO,CAAC,CAAA,CAAA,CAAA;AAAA,IACjC,CAAC,CAAA;AACD,IAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,eAAA,EAAa,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACtD;AAEA,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,GAAA,CAAI,QAAgB,GAAA,EAAqB;AACvC,MAAA,MAAM,EAAA,GAAK,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAClE,MAAA,cAAA,CAAe,GAAA,CAAI,IAAI,EAAE,MAAA,EAAQ,KAAK,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAG,CAAA;AAC7D,MAAA,cAAA,EAAe;AACf,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,aAAA,GAAgB,WAAA,CAAY,gBAAgB,GAAG,CAAA;AAAA,MACjD;AACA,MAAA,OAAO,EAAA;AAAA,IACT,CAAA;AAAA,IACA,OAAO,EAAA,EAAY;AACjB,MAAA,cAAA,CAAe,OAAO,EAAE,CAAA;AACxB,MAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,QAAA,OAAA,CAAQ,MAAA,CAAO,MAAM,UAAU,CAAA;AAC/B,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,aAAA,CAAc,aAAa,CAAA;AAC3B,UAAA,aAAA,GAAgB,IAAA;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAM,WAAA,GAAc,EAAE,MAAA,EAAQ,EAAA,EAAI,KAAK,EAAA,EAAI,SAAA,EAAW,CAAA,EAAG,SAAA,EAAW,EAAA,EAAG;AAEvE,EAAA,MAAM,kBAQF,EAAC;AAEL,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC9C,EAAA,MAAM,cAAA,GAA+B,OAAO,KAAA,EAAO,IAAA,KAAS;AAC1D,IAAA,MAAM,GAAA,GACJ,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,iBAAiB,GAAA,GAAM,KAAA,CAAM,QAAA,EAAS,GAAI,KAAA,CAAM,GAAA;AACtF,IAAA,MAAM,UAAU,IAAA,EAAM,MAAA,IAAU,KAAA,EAAO,MAAA,IAAU,OAAO,WAAA,EAAY;AACpE,IAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,IAAA,EAAM,OAAO,CAAA;AACpD,IAAA,IAAI,OAAA,GAAmB,MAAA;AACvB,IAAA,IAAI,IAAA,EAAM,QAAQ,IAAA,EAAM;AACtB,MAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,QAAA,OAAA,GAAU,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA,MAClC,CAAA,MAAA,IACE,IAAA,CAAK,IAAA,YAAgB,WAAA,EACrB;AACA,QAAA,OAAA,GAAU,aAAa,IAAI,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MAC5D,CAAA,MAAA,IAAW,WAAA,CAAY,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AACxC,QAAA,OAAA,GAAU,aAAa,IAAI,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MAC5D,CAAA,MAAO;AACL,QAAA,OAAA,GAAU,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,MAC5B;AAAA,IACF;AACA,IAAA,eAAA,CAAgB,UAAU,EAAE,GAAA,EAAK,QAAQ,OAAA,EAAS,UAAA,EAAY,MAAM,OAAA,EAAQ;AAE5E,IAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AAExC,IAAA,IAAI,CAAC,KAAK,EAAA,EAAI;AACZ,MAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,EAAM;AACzB,MAAA,MAAM,OAAO,MAAM,KAAA,CAAM,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC9C,MAAA,eAAA,CAAgB,QAAA,GAAW;AAAA,QACzB,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,YAAY,IAAA,CAAK,UAAA;AAAA,QACjB,OAAA,EAAS,eAAA,CAAgB,IAAA,CAAK,OAAO,CAAA;AAAA,QACrC,IAAA,EAAM,aAAa,IAAI;AAAA,OACzB;AAAA,IACF,CAAA,MAAO;AACL,MAAA,eAAA,CAAgB,QAAA,GAAW,MAAA;AAAA,IAC7B;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,WAAWA,yBAAA,CAAqB;AAAA,IACpC,gBAAgB,OAAA,CAAQ,cAAA;AAAA,IACxB,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,gBAAgB,OAAA,CAAQ,cAAA;AAAA,IACxB,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,IAC1B,KAAA,EAAO,cAAA;AAAA,IACP,gBAAA,EAAkB,YAChB,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,WAAA,EAAY,EAAG,CAAA,EAAG;AAAA,MAChE,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAAA,IACH,YAAA,EAAc,CAAC,KAAA,KAAU;AACvB,MAAA,MAAM,aAAa,WAAA,CAAY,SAAA,GAAY,KAAK,GAAA,EAAI,GAAI,YAAY,SAAA,GAAY,CAAA;AAChF,MAAA,MAAM,YAAA,GAAe,KAAA,CAAM,WAAA,GAAc,KAAA,CAAM,eAAe,KAAA,CAAM,YAAA;AACpE,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,CAAA,MAAA,EAAS,MAAM,WAAW,CAAA,CAAA;AAAA,QAC1B,CAAA,MAAA,EAAS,MAAM,WAAW,CAAA,CAAA;AAAA,QAC1B,CAAA,OAAA,EAAU,MAAM,YAAY,CAAA,CAAA;AAAA,QAC5B,CAAA,OAAA,EAAU,MAAM,YAAY,CAAA,CAAA;AAAA,QAC5B,UAAU,YAAY,CAAA;AAAA,OACxB;AACA,MAAA,IAAI,KAAA,CAAM,sBAAsB,CAAA,EAAG;AACjC,QAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,KAAA,CAAM,mBAAmB,CAAA,CAAE,CAAA;AAAA,MAC1D;AACA,MAAA,MAAM,GAAA,GAAM,qBAAqB,UAAU,CAAA;AAC3C,MAAA,MAAM,KAAA,GAAQ,GAAA,GAAM,CAAA,GAAI,UAAA,GAAa,GAAA,GAAM,CAAA;AAC3C,MAAA,MAAM,QAAQ,KAAA,GAAQ,GAAA,GAAM,UAAA,GAAa,KAAA,GAAQ,MAAM,UAAA,GAAa,UAAA;AACpE,MAAA,MAAM,KAAA,GAAQ,SAAA;AACd,MAAA,MAAM,MAAA,GAAS,CAAA,CAAA,EAAI,OAAA,iBAAQ,IAAI,IAAA,EAAM,CAAC,CAAA,UAAA,EAAa,KAAK,CAAA,EAAG,WAAA,CAAY,UAAU,CAAC,GAAG,KAAK,CAAA,KAAA,EAAQ,WAAA,CAAY,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAC,CAAA,GAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AACpJ,MAAA,WAAA,CAAY,SAAA,GACV,MAAM,YAAA,GAAe,IAAA,IAAQ,eAAe,CAAA,GAAI,CAAA,yBAAA,EAAkB,MAAM,CAAA,CAAA,GAAK,MAAA;AAE/E,MAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,QAAA,OAAA,CAAQ,YAAA,CAAa;AAAA,UACnB,GAAG,KAAA;AAAA,UACH,MAAA,EAAQ,YAAY,MAAA,IAAU,MAAA;AAAA,UAC9B,GAAA,EAAK,YAAY,GAAA,IAAO,MAAA;AAAA,UACxB,YAAY,UAAA,IAAc;AAAA,SAC3B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACD,CAAA;AAED,EAAA,MAAM,MAAA,GAASC,qBAAA,CAAK,YAAA,CAAa,OAAO,KAAK,GAAA,KAAQ;AACnD,IAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,EAAI;AACvB,IAAA,WAAA,CAAY,MAAA,GAAS,IAAI,MAAA,IAAU,MAAA;AACnC,IAAA,WAAA,CAAY,GAAA,GAAM,IAAI,GAAA,IAAO,eAAA;AAC7B,IAAA,WAAA,CAAY,SAAA,GAAY,KAAA;AAExB,IAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,EAAgB;AAC5C,IAAA,MAAM,YAAY,OAAA,CAAQ,SAAA;AAC1B,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI,SAAA,IAAa,YAAY,CAAA,EAAG;AAC9B,MAAA,YAAA,GAAe,WAAW,MAAM;AAC9B,QAAA,MAAA,EAAQ,IAAA,CAAK,CAAA,2BAAA,EAA8B,SAAS,CAAA,YAAA,CAAc,CAAA;AAClE,QAAA,eAAA,CAAgB,KAAA,EAAM;AACtB,QAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,QAAA,GAAA,CAAI,OAAA,EAAQ;AAAA,MACd,GAAG,SAAS,CAAA;AAAA,IACd;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,aAAA,CAAc,KAAK,GAAA,EAAK;AAAA,QAC5B,QAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA,EAAQ,IAAI,MAAA,IAAU,MAAA;AAAA,QACtB,GAAA,EAAK,IAAI,GAAA,IAAO,GAAA;AAAA,QAChB,eAAA;AAAA,QACA,WAAA;AAAA,QACA,cAAA;AAAA,QACA,QAAQ,eAAA,CAAgB;AAAA,OACzB,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAA,EAAQ,KAAA,CAAM,iBAAiB,GAAG,CAAA;AAElC,MAAA,IAAI;AACF,QAAA,IAAI,CAAC,IAAI,WAAA,EAAa;AACpB,UAAA,GAAA,CAAI,SAAA,CAAU,GAAA,EAAK,EAAE,cAAA,EAAgB,oBAAoB,CAAA;AACzD,UAAA,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,EAAE,OAAA,EAAS,uBAAA,EAAwB,EAAG,CAAC,CAAA;AAAA,QACzE;AAAA,MAEF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,YAAA,CAAa,YAAY,CAAA;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACC,QAAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,MAAM;AAC9B,MAAA,MAAM,cAAc,MAAM;AAExB,QAAA,MAAM,IAAA,GAAO,OAAO,OAAA,EAAQ;AAC5B,QAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACd,CAAA,GAAG;AACH,MAAA,MAAM,GAAA,GAAM,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AACxC,MAAA,MAAA,EAAQ,GAAA,CAAI,CAAA,mBAAA,EAAsB,GAAG,CAAA,CAAE,CAAA;AACvC,MAAA,MAAA,EAAQ,GAAA,CAAI,CAAA,iBAAA,EAAoB,OAAA,CAAQ,cAAc,CAAA,CAAE,CAAA;AACxD,MAAA,MAAA,EAAQ,GAAA,CAAI,CAAA,cAAA,EAAiB,OAAA,CAAQ,OAAO,CAAA,CAAE,CAAA;AAC9C,MAAAA,QAAAA,CAAQ;AAAA,QACN,IAAA;AAAA,QACA,IAAA,EAAM,UAAA;AAAA,QACN,GAAA;AAAA,QACA,MAAA;AAAA,QACA,KAAA,EAAO,MACL,IAAI,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACnB,UAAA,MAAA,CAAO,KAAA,CAAM,CAAC,GAAA,KAAQ;AAEpB,YAAA,IAAI,GAAA,EAAK;AACP,cAAA,MAAA,EAAQ,IAAA,CAAK,yBAAyB,GAAG,CAAA;AAAA,YAC3C;AAEA,YAAA,GAAA,EAAI;AAAA,UACN,CAAC,CAAA;AAAA,QACH,CAAC;AAAA,OACJ,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EAC7B,CAAC,CAAA;AACH;AAEA,eAAe,aAAA,CACb,GAAA,EACA,GAAA,EACA,IAAA,EAmBe;AACf,EAAA,IAAI,KAAK,IAAA,EAAM;AACb,IAAA,cAAA,CAAe,GAAG,CAAA;AAAA,EACpB;AAEA,EAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAC5B,IAAA,GAAA,CAAI,UAAU,GAAG,CAAA;AACjB,IAAA,GAAA,CAAI,GAAA,EAAI;AACR,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,IAAU,KAAA;AAC7B,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,IAAO,GAAA;AAC3B,EAAA,MAAM,OAAA,GAAU,sBAAA,CAAuB,GAAA,CAAI,OAAO,CAAA;AAElD,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,MAAA,KAAW,KAAA,IAAS,MAAA,KAAW,MAAA,EAAQ;AACzC,IAAA,IAAA,GAAO,MAAM,iBAAiB,GAAG,CAAA;AAAA,EACnC;AAEA,EAAA,IAAI,CAAC,6BAAA,CAA8B,IAAA,CAAK,OAAO,CAAA,EAAG;AAChD,IAAA,GAAA,CAAI,SAAA,CAAU,GAAA,EAAK,EAAE,cAAA,EAAgB,oBAAoB,CAAA;AACzD,IAAA,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,EAAE,OAAO,EAAE,OAAA,EAAS,CAAA,WAAA,EAAc,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,EAAG,EAAG,CAAC,CAAA;AACjF,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,eAAA,GAAkB,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,GAAI,MAAA;AAEvD,EAAA,MAAM,YAAA,GAAe,KAAK,GAAA,EAAI;AAC9B,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,QAAQ,OAAO,CAAA;AAGzD,EAAA,IAAI;AACF,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,QAAA,CAAS,CAAA,YAAA,EAAe,OAAO,CAAA,CAAA,EAAI;AAAA,MAC7D,MAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA,EAAM,IAAA,GAAO,IAAI,UAAA,CAAW,IAAI,CAAA,GAAI,KAAA,CAAA;AAAA,MACpC,QAAQ,IAAA,CAAK;AAAA,KACd,CAAA;AAGD,IAAA,MAAM,gBAAA,GAAmB,SAAS,IAAA,GAAO,MAAM,SAAS,KAAA,EAAM,CAAE,MAAK,GAAI,EAAA;AAGzE,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,SAAS,CAAA;AAEpC,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAC1B,QAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,UACb,CAAA,YAAA,EAAe,SAAS,MAAM,CAAA,GAAA,EAAM,YAAY,IAAA,CAAK,GAAA,EAAI,GAAI,YAAY,CAAC,CAAA;AAAA;AAAA,SAC5E;AAAA,MACF,CAAA,MAAA,IAAW,IAAA,CAAK,WAAA,CAAY,SAAA,EAAW;AACrC,QAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,QAAA,EAAW,IAAA,CAAK,YAAY,SAAS;AAAA,CAAI,CAAA;AAAA,MAChE,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,UACb,CAAA,YAAA,EAAe,SAAS,MAAM,CAAA,GAAA,EAAM,YAAY,IAAA,CAAK,GAAA,EAAI,GAAI,YAAY,CAAC,CAAA;AAAA;AAAA,SAC5E;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,UAAU,GAAA,EAAK;AAE1B,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,aAAA,CAAc;AAAA,UAC7B,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,KAAK,IAAA,CAAK,GAAA;AAAA,UACV,aAAA,EAAe;AAAA,YACb,OAAA;AAAA,YACA,IAAA,EAAM,YAAA,CAAa,eAAA,IAAmB,EAAE;AAAA,WAC1C;AAAA,UACA,eAAA,EAAiB,KAAK,eAAA,CAAgB,OAAA;AAAA,UACtC,gBAAA,EAAkB,KAAK,eAAA,CAAgB,QAAA;AAAA,UACvC,aAAA,EAAe;AAAA,YACb,QAAQ,QAAA,CAAS,MAAA;AAAA,YACjB,OAAA,EAAS,eAAA,CAAgB,QAAA,CAAS,OAAO,CAAA;AAAA,YACzC,IAAA,EAAM,aAAa,gBAAgB;AAAA;AACrC,SACD,CAAA;AACD,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,CAAA,uCAAA,EAA0C,QAAQ,CAAA,CAAE,CAAA;AAAA,MACzE,SAAS,OAAA,EAAS;AAChB,QAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,8CAAA,EAAgD,OAAO,CAAA;AAAA,MAC5E;AAAA,IACF;AAEA,IAAA,MAAM,aAAqC,EAAC;AAC5C,IAAA,QAAA,CAAS,OAAA,CAAQ,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AACvC,MAAA,UAAA,CAAW,GAAG,CAAA,GAAI,KAAA;AAAA,IACpB,CAAC,CAAA;AACD,IAAA,IAAI,KAAK,IAAA,EAAM;AACb,MAAA,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,WAAA,EAAa,CAAA;AAAA,IACzC;AAEA,IAAA,GAAA,CAAI,SAAA,CAAU,QAAA,CAAS,MAAA,EAAQ,UAAU,CAAA;AAGzC,IAAA,IAAI,CAAC,SAAS,IAAA,EAAM;AAClB,MAAA,GAAA,CAAI,GAAA,EAAI;AACR,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAC3B,IAAA,MAAM,UAAA,GAAaC,eAAA,CAAS,OAAA,CAAQ,SAAS,CAAA;AAC7C,IAAA,UAAA,CAAW,KAAK,GAAG,CAAA;AACnB,IAAA,MAAM,IAAI,OAAA,CAAc,CAACD,QAAAA,EAAS,MAAA,KAAW;AAC3C,MAAA,UAAA,CAAW,IAAA,CAAK,OAAOA,QAAO,CAAA;AAC9B,MAAA,UAAA,CAAW,IAAA,CAAK,SAAS,MAAM,CAAA;AAC/B,MAAA,GAAA,CAAI,IAAA,CAAK,SAASA,QAAO,CAAA;AAAA,IAC3B,CAAC,CAAA;AAAA,EACH,SAAS,GAAA,EAAK;AACZ,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,SAAS,CAAA;AACpC,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAEA,SAAS,iBAAiB,GAAA,EAAuC;AAC/D,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACA,QAAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,GAAA,CAAI,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAU;AACxB,MAAA,MAAM,GAAA,GAAc,KAAA;AACpB,MAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,IACjB,CAAC,CAAA;AACD,IAAA,GAAA,CAAI,EAAA,CAAG,OAAO,MAAMA,QAAAA,CAAQ,OAAO,MAAA,CAAO,MAAM,CAAC,CAAC,CAAA;AAClD,IAAA,GAAA,CAAI,EAAA,CAAG,SAAS,MAAM,CAAA;AAAA,EACxB,CAAC,CAAA;AACH;AAEO,SAAS,uBACd,OAAA,EACwB;AACxB,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,IAAI,SAAS,IAAA,EAAM;AACjB,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,OAAO,KAAK,CAAA;AAAA,EACjF;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,gBAAgB,OAAA,EAA0C;AACxE,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC9B,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA;AAAA,EACb,CAAC,CAAA;AACD,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,eAAe,GAAA,EAA2B;AACjD,EAAA,MAAM,UAAU,WAAA,EAAY;AAC5B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,GAAA,CAAI,SAAA,CAAU,KAAK,KAAK,CAAA;AAAA,EAC1B;AACF;AAEO,SAAS,WAAA,GAAsC;AACpD,EAAA,OAAO;AAAA,IACL,6BAAA,EAA+B,GAAA;AAAA,IAC/B,8BAAA,EAAgC,kBAAA;AAAA,IAChC,8BAAA,EACE,iHAAA;AAAA,IACF,+BAAA,EAAiC;AAAA,GACnC;AACF;AAEO,SAAS,aAAa,GAAA,EAAyC;AACpE,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,GAAA,IAAO,IAAA;AAAA,EAChB;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAA;AAAA,EACT;AACF;AAEO,SAAS,oBAAoB,WAAA,EAA8D;AAChG,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,WAAA,YAAuB,OAAA,EAAS;AACpE,IAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AAClC,MAAA,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,CAAA,GAAI,KAAA;AAAA,IAC3B,CAAC,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC9B,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,WAAA,EAAa;AACtC,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,aAAa,CAAA,GAAI,OAAO,KAAK,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,EAAG;AACtD,IAAA,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,CAAA,GAAI,OAAO,KAAK,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,cAAc,IAAA,EAYnB;AACT,EAAA,MAAM,GAAA,GAAMA,YAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,MAAM,CAAA;AACzC,EAAAE,YAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAClC,EAAA,MAAM,EAAA,GAAA,qBAAS,IAAA,EAAK,EAAE,aAAY,CAAE,OAAA,CAAQ,SAAS,GAAG,CAAA;AACxD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,EAAkB,MAAA,IAAU,KAAK,aAAA,CAAc,MAAA;AACnE,EAAA,MAAM,QAAA,GAAW,CAAA,YAAA,EAAe,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA,KAAA,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAWC,SAAA,CAAK,GAAA,EAAK,QAAQ,CAAA;AACnC,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IAClC,GAAG;AAAA,GACL;AACA,EAAA,UAAA,CAAW,OAAA,CAAQ,eAAe,OAAO,CAAA;AACzC,EAAA,UAAA,CAAW,OAAA,CAAQ,iBAAiB,OAAO,CAAA;AAC3C,EAAAC,gBAAA,CAAc,UAAU,IAAA,CAAK,SAAA,CAAU,OAAA,EAAS,IAAA,EAAM,CAAC,CAAC,CAAA;AACxD,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,WAAW,OAAA,EAAmD;AAC5E,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA;AAAA,EACF;AACA,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,EAAG;AACtC,IAAA,MAAM,QAAA,GAAW,IAAI,WAAA,EAAY;AACjC,IAAA,IACE,aAAa,eAAA,IACb,QAAA,KAAa,eACb,QAAA,KAAa,SAAA,IACb,aAAa,QAAA,EACb;AACA,MAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,YAAA;AAAA,IACjB;AAAA,EACF;AACF;AC5eO,SAAS,eAAe,MAAA,EAAqD;AAClF,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,IAAA,EAAM;AACjD,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,0BAAA,EAA2B;AAAA,EAC3D;AAGA,EAAA,MAAM,GAAA,GAA+B,MAAA;AAErC,EAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,mCAAA,EAAoC;AAAA,EACpE;AAEA,EAAA,IAAI,OAAO,GAAA,CAAI,eAAA,KAAoB,QAAA,EAAU;AAC3C,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,2CAAA,EAA4C;AAAA,EAC5E;AAEA,EAAA,IAAI,OAAO,GAAA,CAAI,SAAA,KAAc,QAAA,IAAY,GAAA,CAAI,cAAc,IAAA,EAAM;AAC/D,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,sCAAA,EAAuC;AAAA,EACvE;AAGA,EAAA,MAAM,YAAqC,GAAA,CAAI,SAAA;AAE/C,EAAA,IAAI,EAAE,GAAA,CAAI,eAAA,IAAmB,SAAA,CAAA,EAAY;AACvC,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP,KAAA,EAAO,CAAA,iBAAA,EAAoB,GAAA,CAAI,eAAe,CAAA,wBAAA;AAAA,KAChD;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,QAAQ,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AACxD,IAAA,MAAM,MAAA,GAAS,uBAAuB,QAAQ,CAAA;AAC9C,IAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,KAAA;AAAA,QACP,KAAA,EAAO,CAAA,UAAA,EAAa,IAAI,CAAA,cAAA,EAAiB,OAAO,KAAK,CAAA;AAAA,OACvD;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAEO,SAAS,uBAAuB,QAAA,EAGrC;AACA,EAAA,IAAI,OAAO,QAAA,KAAa,QAAA,IAAY,QAAA,KAAa,IAAA,EAAM;AACrD,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,mCAAA,EAAoC;AAAA,EACpE;AAGA,EAAA,MAAM,GAAA,GAA+B,QAAA;AAErC,EAAA,IAAI,GAAA,CAAI,WAAW,MAAA,EAAW;AAC5B,IAAA,IAAI,OAAO,GAAA,CAAI,MAAA,KAAW,QAAA,EAAU;AAClC,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,qCAAA,EAAsC;AAAA,IACtE;AACA,IAAA,MAAM,YAAA,GAAe,CAAC,WAAA,EAAa,aAAa,CAAA;AAChD,IAAA,IAAI,CAAC,YAAA,CAAa,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AACtC,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,KAAA;AAAA,QACP,KAAA,EAAO,mBAAmB,GAAA,CAAI,MAAM,qBAAqB,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,OAClF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,0CAAA,EAA2C;AAAA,EAC3E;AAEA,EAAA,IAAI,IAAI,UAAA,KAAe,MAAA,IAAa,OAAO,GAAA,CAAI,eAAe,QAAA,EAAU;AACtE,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,yCAAA,EAA0C;AAAA,EAC1E;AAEA,EAAA,IAAI,IAAI,MAAA,KAAW,MAAA,IAAa,OAAO,GAAA,CAAI,WAAW,QAAA,EAAU;AAC9D,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,qCAAA,EAAsC;AAAA,EACtE;AAEA,EAAA,IAAI,IAAI,KAAA,KAAU,MAAA,IAAa,OAAO,GAAA,CAAI,UAAU,QAAA,EAAU;AAC5D,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,oCAAA,EAAqC;AAAA,EACrE;AAEA,EAAA,IAAI,IAAI,UAAA,KAAe,MAAA,IAAa,OAAO,GAAA,CAAI,eAAe,SAAA,EAAW;AACvE,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,0CAAA,EAA2C;AAAA,EAC3E;AAEA,EAAA,IAAI,IAAI,QAAA,KAAa,MAAA,IAAa,OAAO,GAAA,CAAI,aAAa,QAAA,EAAU;AAClE,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,uCAAA,EAAwC;AAAA,EACxE;AAEA,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,KAAc,OAAO,IAAI,OAAA,KAAY,QAAA,IAAY,GAAA,CAAI,OAAA,KAAY,IAAA,CAAA,EAAO;AAC1F,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,uCAAA,EAAwC;AAAA,EACxE;AAEA,EAAA,IAAI,IAAI,eAAA,KAAoB,MAAA,IAAa,OAAO,GAAA,CAAI,oBAAoB,QAAA,EAAU;AAChF,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,8CAAA,EAA+C;AAAA,EAC/E;AAIA,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAKO,SAAS,yBAAyB,MAAA,EAA2C;AAClF,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,SAAA,CAAU,MAAA,CAAO,eAAe,CAAA;AACxD,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAA;AACT;;;AClKO,SAAS,UAAU,IAAA,EAAyB;AACjD,EAAA,MAAM,MAAe,EAAC;AACtB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,MAAM,GAAA,GAAM,KAAK,CAAC,CAAA;AAClB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,EAAE,CAAC,CAAA;AAC3B,IAAA,QAAQ,GAAA;AAAK,MACX,KAAK,IAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AACX,QAAA;AAAA,MACF,KAAK,IAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAA,GAAA,CAAI,IAAA,GAAO,MAAA,CAAO,IAAA,EAAM,CAAA;AACxB,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,GAAA,CAAI,OAAO,IAAA,EAAK;AAChB,QAAA;AAAA,MACF,KAAK,mBAAA;AACH,QAAA,GAAA,CAAI,iBAAiB,IAAA,EAAK;AAC1B,QAAA;AAAA,MACF,KAAK,YAAA;AACH,QAAA,GAAA,CAAI,UAAU,IAAA,EAAK;AACnB,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,GAAA,CAAI,SAAS,IAAA,EAAK;AAClB,QAAA;AAAA,MACF,KAAK,eAAA;AACH,QAAA,GAAA,CAAI,aAAa,IAAA,EAAK;AACtB,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,GAAA,CAAI,SAAS,IAAA,EAAK;AAClB,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,GAAA,CAAI,QAAQ,IAAA,EAAK;AACjB,QAAA;AAAA,MACF,KAAK,eAAA;AACH,QAAA,GAAA,CAAI,UAAA,GAAa,IAAA;AACjB,QAAA;AAAA,MACF,KAAK,WAAA;AACH,QAAA,GAAA,CAAI,IAAA,GAAO,KAAA;AACX,QAAA;AAAA,MACF;AACE,QAAA,IAAI,GAAA,CAAI,UAAA,CAAW,oBAAoB,CAAA,EAAG;AACxC,UAAA,GAAA,CAAI,cAAA,GAAiB,GAAA,CAAI,KAAA,CAAM,oBAAA,CAAqB,MAAM,CAAA;AAAA,QAC5D,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACpC,UAAA,GAAA,CAAI,OAAO,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,QAC/C,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACpC,UAAA,GAAA,CAAI,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA;AAAA,QACvC,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AACxC,UAAA,GAAA,CAAI,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,aAAA,CAAc,MAAM,CAAA;AAAA,QAC9C,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,gBAAgB,CAAA,EAAG;AAC3C,UAAA,GAAA,CAAI,UAAA,GAAa,GAAA,CAAI,KAAA,CAAM,gBAAA,CAAiB,MAAM,CAAA;AAAA,QACpD,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AACtC,UAAA,GAAA,CAAI,MAAA,GAAS,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA;AAAA,QAC3C,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,UAAU,CAAA,EAAG;AACrC,UAAA,GAAA,CAAI,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA;AAAA,QACzC,CAAA,MAAA,IAAW,GAAA,CAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AACtC,UAAA,GAAA,CAAI,MAAA,GAAS,GAAA,CAAI,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA;AAAA,QAC3C,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,kBAAA,EAAqB,GAAG,CAAA,CAAE,CAAA;AACxC,UAAA,GAAA,CAAI,IAAA,GAAO,IAAA;AAAA,QACb;AAAA;AACJ,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,SAAA,GAAkB;AAChC,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAoDb,CAAA;AACD;AAEA,eAAsB,eAAe,UAAA,EAAyC;AAC5E,EAAA,IAAI,CAACC,aAAAA,CAAW,UAAU,CAAA,EAAG;AAC3B,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,uBAAA,EAA0B,UAAU,CAAA,CAAE,CAAA;AACpD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAUC,eAAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AAChD,IAAA,MAAM,MAAA,GAAqB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAC7C,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,2BAAA,EAA8B,UAAU,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAChE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAEA,eAAsB,2BAAA,CACpB,YACA,SAAA,EAC4B;AAC5B,EAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,UAAU,CAAA;AAE9C,EAAA,MAAM,UAAA,GAAa,eAAe,MAAM,CAAA;AACxC,EAAA,IAAI,CAAC,WAAW,KAAA,EAAO;AACrB,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,qBAAA,EAAwB,UAAA,CAAW,KAAK,CAAA,CAAE,CAAA;AACxD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,cAAA,GAAiB,yBAAyB,MAAM,CAAA;AAChC,EAAA,IAAI,CAAC,cAAA,EAAgB;AACzC,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,kBAAA,EAAqB,MAAA,CAAO,eAAe,CAAA,qBAAA,CAAuB,CAAA;AAChF,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,oBAAA,EAAuB,UAAU,CAAA,CAAE,CAAA;AAC/C,EAAA,OAAA,CAAQ,GAAA;AAAA,IACN,CAAA,kBAAA,EAAqB,MAAA,CAAO,eAAe,CAAA,EAAG,cAAA,CAAe,SAAS,CAAA,EAAA,EAAK,cAAA,CAAe,MAAM,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA;AAAA,GAC1G;AACA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,OAAA,EAAU,cAAA,CAAe,KAAA,IAAS,WAAW,CAAA,CAAE,CAAA;AAC3D,EAAA,MAAM,YAAA,GAAe,cAAA,CAAe,eAAA,IAAmB,MAAA,CAAO,eAAA;AAC9D,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,kBAAA,EAAqB,YAAY,CAAA,CAAE,CAAA;AAAA,EACjD;AACA,EAAA,MAAM,gBAAwC,EAAE,GAAI,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG;AAC1E,EAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,IAAA,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe,cAAA,CAAe,OAAO,CAAA;AAAA,EACrD;AACA,EAAA,IAAI,cAAc,aAAA,EAAe;AAC/B,IAAA,aAAA,CAAc,aAAA,GAAgB,cAAA;AAAA,EAChC;AACA,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,CAAE,SAAS,CAAA,EAAG;AACzC,IAAA,OAAA,CAAQ,IAAI,CAAA,SAAA,EAAY,IAAA,CAAK,SAAA,CAAU,aAAa,CAAC,CAAA,CAAE,CAAA;AAAA,EACzD;AAKA,EAAA,MAAM,OAAA,GAA6B;AAAA,IACjC,gBAAgB,cAAA,CAAe,MAAA;AAAA,IAC/B,OAAA,EAAS,SAAA,CAAU,OAAA,IAAW,cAAA,CAAe,OAAA;AAAA,IAC7C,UAAA,EAAY,SAAA,CAAU,UAAA,IAAc,cAAA,CAAe,UAAA;AAAA,IACnD,KAAA,EAAO,SAAA,CAAU,KAAA,IAAS,cAAA,CAAe,KAAA;AAAA,IACzC,IAAA,EAAM,SAAA,CAAU,IAAA,IAAQ,cAAA,CAAe,IAAA;AAAA,IACvC,IAAA,EACE,SAAA,CAAU,IAAA,KAAS,MAAA,GACf,SAAA,CAAU,IAAA;AAAA;AAAA,MAET,MAAA,CAA8C,IAAA;AAAA;AAAA,QAE7C,MAAA,CAAQ,OAA8C,IAAI;AAAA,UAC1D,cAAA,CAAe,IAAA,GACb,MAAA,CAAO,cAAA,CAAe,IAAI,CAAA,GAC1B;AAAA,KAAA;AAAA,IACV,SAAA,EAAW,cAAA,CAAe,SAAA,IAAa,MAAA,CAAO,SAAA;AAAA,IAC9C,YAAY,cAAA,CAAe,UAAA;AAAA,IAC3B,MAAM,SAAA,CAAU,IAAA;AAAA,IAChB,gBAAA,EAAkB,cAAA,CAAe,eAAA,IAAmB,MAAA,CAAO,eAAA;AAAA,IAC3D,QAAA,EAAU,cAAA,CAAe,QAAA,IAAY,MAAA,CAAO;AAAA,GAC9C;AAEA,EAAA,MAAM,iBAAyC,EAAE,GAAI,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG;AAC3E,EAAA,IAAI,eAAe,OAAA,EAAS;AAC1B,IAAA,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,cAAA,CAAe,OAAO,CAAA;AAAA,EACtD;AACA,EAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,IAAA,cAAA,CAAe,aAAA,GAAgB,CAAA,OAAA,EAAU,cAAA,CAAe,MAAM,CAAA,CAAA;AAAA,EAChE;AACA,EAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,IAAA,cAAA,CAAe,aAAA,GAAgB,CAAA,OAAA,EAAU,SAAA,CAAU,MAAM,CAAA,CAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,cAAc,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1C,IAAA,OAAA,CAAQ,cAAA,GAAiB,cAAA;AAAA,EAC3B;AAGA,EAAA,IAAI,eAAe,QAAA,EAAU;AAC3B,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,QAAQ,CAAA;AACzD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,MAAM,YAAoC,EAAE,GAAI,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG;AACtE,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,QAAA,CAAS,OAAO,CAAA;AAAA,MAC3C;AACA,MAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,QAAA,SAAA,CAAU,aAAA,GAAgB,CAAA,OAAA,EAAU,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,MACrD;AACA,MAAA,MAAM,WAAuC,QAAA,CAAS,MAAA;AACtD,MAAA,OAAA,CAAQ,gBAAA,GAAmB;AAAA,QACzB,SAAS,QAAA,CAAS,OAAA;AAAA,QAClB,cAAA,EAAgB,QAAA;AAAA,QAChB,KAAA,EAAO,QAAA,CAAS,KAAA,IAAS,OAAA,CAAQ,KAAA;AAAA,QACjC,gBAAgB,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,MAAA,GAAS,IAAI,SAAA,GAAY,MAAA;AAAA,QAChE,UAAA,EAAY,QAAA,CAAS,UAAA,IAAc,OAAA,CAAQ,UAAA;AAAA,QAC3C,gBAAA,EAAkB,QAAA,CAAS,eAAA,IAAmB,OAAA,CAAQ,gBAAA;AAAA,QACtD,QAAA,EAAU,QAAA,CAAS,QAAA,IAAY,OAAA,CAAQ;AAAA,OACzC;AACA,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,mBAAA,EAAsB,cAAA,CAAe,QAAQ,CAAA,EAAG,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA;AAAA,OAC9F;AAAA,IACF,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,4BAAA,EAA+B,cAAA,CAAe,QAAQ,CAAA,qBAAA,CAAuB,CAAA;AAAA,IAC5F;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAGA,eAAsB,IAAA,GAAsB;AAC1C,EAAA,MAAM,OAAO,SAAA,CAAU,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AAE5C,EAAA,IAAI,KAAK,IAAA,EAAM;AACb,IAAA,SAAA,EAAU;AACV,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,IAAI,OAAA;AAEJ,EAAA,IAAI,KAAK,MAAA,EAAQ;AACf,IAAA,OAAA,GAAU,MAAM,2BAAA,CAA4B,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AAAA,EAC/D,CAAA,MAAA,IAAW,KAAK,OAAA,EAAS;AAEvB,IAAA,MAAM,iBAAiB,IAAA,CAAK,cAAA;AAC5B,IAAA,OAAA,GAAU;AAAA,MACR,cAAA;AAAA,MACA,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,cAAA,EAAgB,KAAK,MAAA,GAAS,EAAE,eAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA,EAAG,GAAI,MAAA;AAAA,MAC3E,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,MAAM,IAAA,CAAK;AAAA,KACb;AAAA,EACF,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,MAAM,+DAA+D,CAAA;AAC7E,IAAA,OAAA,CAAQ,MAAM,EAAE,CAAA;AAChB,IAAA,SAAA,EAAU;AACV,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,CAAW,OAAO,CAAA;AAEtC,EAAA,MAAM,QAAA,GAAW,OAAO,MAAA,KAAmB;AACzC,IAAA,OAAA,CAAQ,GAAA,CAAI;AAAA,SAAA,EAAc,MAAM,CAAA,kBAAA,CAAoB,CAAA;AAEpD,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,KAAA,EAAM;AAAA,IACpB,CAAA,SAAE;AACA,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EACF,CAAA;AACA,EAAA,OAAA,CAAQ,GAAG,QAAA,EAAU,MAAM,KAAK,QAAA,CAAS,QAAQ,CAAC,CAAA;AAClD,EAAA,OAAA,CAAQ,GAAG,SAAA,EAAW,MAAM,KAAK,QAAA,CAAS,SAAS,CAAC,CAAA;AAEtD;AAGA,IAAI,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,SAAS,QAAQ,CAAA,IAAK,QAAQ,IAAA,CAAK,CAAC,GAAG,QAAA,CAAS,QAAQ,KAAK,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,QAAA,CAAS,WAAW,CAAA,EAAG;AACxH,EAAA,KAAK,IAAA,EAAK;AACZ","file":"cli.cjs","sourcesContent":["// ==============================================================================\n// Helpers\n// ==============================================================================\n\n/**\n * Local HTTP proxy that exposes the Responses API and forwards translated\n * requests to the configured upstream API format.\n */\n\nimport http, { type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport { Readable } from 'node:stream';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\n// ==============================================================================\n// Helpers\n// ==============================================================================\nexport function fmtTime(date: Date): string {\n return date.toLocaleTimeString('en-US', { hour12: false });\n}\n\nexport function fmtDuration(ms: number): string {\n // ==============================================================================\n // Server\n // ==============================================================================\n\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\nimport { createResponsesFetch, type CreateResponsesFetchOptions } from '@codeproxy/core';\n\nexport interface StartProxyOptions extends Omit<CreateResponsesFetchOptions, 'passthroughFetch'> {\n /** Host to bind to. Defaults to `127.0.0.1`. */\n host?: string;\n /** Port to listen on. Defaults to `8787`; pass `0` for a random free port. */\n port?: number;\n /** Enable permissive CORS (useful for local browser dev). Defaults to true. */\n cors?: boolean;\n /** Optional logger. Defaults to `console`. Pass `null` to silence. */\n logger?: Pick<Console, 'log' | 'warn' | 'error'> | null;\n /** Optional callback to receive cache statistics after each request completes. */\n onCacheStats?: (stats: {\n cachedTokens: number;\n cacheCreationTokens: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n method?: string;\n url?: string;\n durationMs?: number;\n }) => void;\n}\n\nexport interface RunningProxy {\n host: string;\n port: number;\n url: string;\n server: Server;\n close: () => Promise<void>;\n}\n\nexport async function startProxy(options: StartProxyOptions): Promise<RunningProxy> {\n const host = options.host ?? '127.0.0.1';\n const port = options.port ?? 8787;\n const cors = options.cors ?? true;\n const logger = options.logger === null ? null : (options.logger ?? console);\n\n // Rolling average for request duration coloring (last 50 requests)\n const durationHistory: number[] = [];\n function updateRollingAverage(ms: number) {\n durationHistory.push(ms); /* c8 ignore next 3 -- threshold rarely hit */\n if (durationHistory.length > 50) {\n durationHistory.shift();\n }\n return durationHistory.reduce((sum, val) => sum + val, 0) / durationHistory.length;\n }\n\n // Centralized status line for all active requests\n const activeRequests = new Map<string, { method: string; url: string; startTime: number }>();\n // ==============================================================================\n // Request Handler\n // ==============================================================================\n\n let statusTimerId: ReturnType<typeof setInterval> | null = null;\n\n function drawStatusLine() {\n if (activeRequests.size === 0) {\n return; /* c8 ignore next -- empty guard */\n }\n const parts = Array.from(activeRequests.entries()).map(([, req]) => {\n const elapsed = Date.now() - req.startTime;\n return `[${fmtDuration(elapsed)}]`;\n });\n process.stdout.write(`\\r\\x1b[K⏳ ${parts.join(', ')}`);\n }\n\n const requestTracker = {\n add(method: string, url: string): string {\n const id = `${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;\n activeRequests.set(id, { method, url, startTime: Date.now() });\n drawStatusLine();\n if (!statusTimerId) {\n statusTimerId = setInterval(drawStatusLine, 150);\n }\n return id;\n },\n remove(id: string) {\n activeRequests.delete(id);\n if (activeRequests.size === 0) {\n process.stdout.write('\\r\\x1b[K');\n if (statusTimerId) {\n clearInterval(statusTimerId);\n statusTimerId = null;\n }\n }\n },\n };\n\n const requestInfo = { method: '', url: '', startTime: 0, resultLog: '' };\n\n const upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n } = {};\n\n const baseFetch = options.fetch ?? globalThis.fetch;\n const capturingFetch: typeof fetch = async (input, init) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? input?.method ?? 'GET').toUpperCase();\n const reqHeaders = headersInitToObject(init?.headers);\n let reqBody: unknown = undefined;\n if (init?.body != null) {\n if (typeof init.body === 'string') {\n reqBody = tryParseJson(init.body);\n } /* c8 ignore next 6 -- defensive body serialization */ else if (\n init.body instanceof ArrayBuffer\n ) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else if (ArrayBuffer.isView(init.body)) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else {\n reqBody = String(init.body);\n }\n }\n upstreamCapture.request = { url, method, headers: reqHeaders, body: reqBody };\n\n const resp = await baseFetch(input, init);\n\n if (!resp.ok) {\n const clone = resp.clone();\n const text = await clone.text().catch(() => '');\n upstreamCapture.response = {\n status: resp.status,\n statusText: resp.statusText,\n headers: headersToObject(resp.headers),\n body: tryParseJson(text),\n };\n } else {\n upstreamCapture.response = undefined;\n }\n return resp;\n };\n\n const apiFetch = createResponsesFetch({\n upstreamFormat: options.upstreamFormat,\n baseUrl: options.baseUrl,\n apiVersion: options.apiVersion,\n model: options.model,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n dropImages: options.dropImages,\n fallbackUpstream: options.fallbackUpstream,\n fetch: capturingFetch,\n passthroughFetch: async () =>\n new Response(JSON.stringify({ error: { message: 'Not found' } }), {\n status: 404,\n headers: { 'content-type': 'application/json' },\n }),\n onCacheStats: (stats) => {\n const durationMs = requestInfo.startTime ? Date.now() - requestInfo.startTime : 0;\n const billedTokens = stats.inputTokens + stats.outputTokens - stats.cachedTokens;\n const parts = [\n `total=${stats.totalTokens}`,\n `input=${stats.inputTokens}`,\n `output=${stats.outputTokens}`,\n `cached=${stats.cachedTokens}`,\n `billed=${billedTokens}`,\n ];\n if (stats.cacheCreationTokens > 0) {\n parts.push(`cache_creation=${stats.cacheCreationTokens}`);\n }\n const avg = updateRollingAverage(durationMs);\n const ratio = avg > 0 ? durationMs / avg : 1;\n const color = ratio < 0.8 ? '\\x1b[32m' : ratio < 1.5 ? '\\x1b[33m' : '\\x1b[31m';\n const reset = '\\x1b[0m';\n const logMsg = `[${fmtTime(new Date())}] -> 200 (${color}${fmtDuration(durationMs)}${reset} avg=${fmtDuration(Math.round(avg))}) [${parts.join(', ')}]`;\n requestInfo.resultLog =\n stats.cachedTokens < 1024 && billedTokens > 0 ? `⚠️ NO CACHE -- ${logMsg}` : logMsg;\n\n if (options.onCacheStats) {\n options.onCacheStats({\n ...stats,\n method: requestInfo.method || undefined,\n url: requestInfo.url || undefined,\n durationMs: durationMs || undefined,\n });\n }\n },\n });\n\n const server = http.createServer(async (req, res) => {\n const start = Date.now();\n requestInfo.method = req.method ?? 'POST';\n requestInfo.url = req.url ?? '/v1/responses';\n requestInfo.startTime = start;\n\n const abortController = new AbortController();\n const timeoutMs = options.timeoutMs;\n let timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n if (timeoutMs && timeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n logger?.warn(`[timeout] request exceeded ${timeoutMs}ms, aborting`);\n abortController.abort();\n res.destroy();\n req.destroy();\n }, timeoutMs);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await handleRequest(req, res, {\n apiFetch,\n cors,\n logger,\n method: req.method ?? 'POST',\n url: req.url ?? '/',\n upstreamCapture,\n requestInfo,\n requestTracker,\n signal: abortController.signal,\n });\n } catch (err) {\n logger?.error('[proxy-error]', err);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: 'Internal server error' } }));\n }\n /* c8 ignore start */\n } catch {\n // ignore\n } /* c8 ignore stop */\n } finally {\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n }\n }\n });\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n const actualPort = (() => {\n // eslint-disable-next-line no-restricted-syntax -- net.Server.address() returns string | AddressInfo | null\n const addr = server.address() as { port: number } | null;\n return addr.port;\n })();\n const url = `http://${host}:${actualPort}`;\n logger?.log(`Proxy listening on ${url}`);\n logger?.log(`Upstream format: ${options.upstreamFormat}`);\n logger?.log(`Upstream URL: ${options.baseUrl}`);\n resolve({\n host,\n port: actualPort,\n url,\n server,\n close: () =>\n new Promise((res) => {\n server.close((err) => {\n /* c8 ignore start */\n if (err) {\n logger?.warn('Error closing server:', err);\n }\n /* c8 ignore stop */\n res();\n });\n }),\n });\n });\n server.once('error', reject);\n });\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n opts: {\n apiFetch: typeof fetch;\n cors: boolean;\n logger: Pick<Console, 'log' | 'warn' | 'error'> | null;\n method: string;\n url: string;\n upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n };\n requestInfo: { resultLog: string };\n requestTracker: { add: (method: string, url: string) => string; remove: (id: string) => void };\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (opts.cors) {\n setCorsHeaders(res);\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const method = req.method ?? 'GET';\n const urlPath = req.url ?? '/';\n const headers = flattenIncomingHeaders(req.headers);\n\n let body: Buffer | undefined;\n if (method !== 'GET' && method !== 'HEAD') {\n body = await readIncomingBody(req);\n }\n\n if (!/^\\/v1\\/responses\\/?(?:\\?|$)/.test(urlPath)) {\n res.writeHead(404, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: `Not found: ${method} ${urlPath}` } }));\n return;\n }\n\n const requestBodyText = body ? body.toString('utf8') : undefined;\n\n const requestStart = Date.now();\n const requestId = opts.requestTracker.add(method, urlPath);\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const response = await opts.apiFetch(`http://local${urlPath}`, {\n method,\n headers,\n body: body ? new Uint8Array(body) : undefined,\n signal: opts.signal,\n });\n\n // Consume response body so onCacheStats fires (for streaming responses)\n const responseBodyText = response.body ? await response.clone().text() : '';\n\n // Remove from active requests and write final result\n opts.requestTracker.remove(requestId);\n /* c8 ignore start */\n if (opts.logger) {\n if (response.status >= 400) {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n } else if (opts.requestInfo.resultLog) {\n process.stdout.write(`\\r\\x1b[K${opts.requestInfo.resultLog}\\n`);\n } else {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n }\n }\n /* c8 ignore stop */\n if (response.status >= 400) {\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const filePath = saveErrorDump({\n method: opts.method,\n url: opts.url,\n clientRequest: {\n headers,\n body: tryParseJson(requestBodyText ?? ''),\n },\n upstreamRequest: opts.upstreamCapture.request,\n upstreamResponse: opts.upstreamCapture.response,\n proxyResponse: {\n status: response.status,\n headers: headersToObject(response.headers),\n body: tryParseJson(responseBodyText),\n },\n });\n opts.logger?.error(`[proxy-failure] full exchange saved to ${filePath}`);\n } catch (dumpErr) {\n opts.logger?.error('[proxy-failure] failed to persist error dump', dumpErr);\n }\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n if (opts.cors) {\n Object.assign(outHeaders, corsHeaders());\n }\n\n res.writeHead(response.status, outHeaders);\n\n /* c8 ignore next 3 */\n if (!response.body) {\n res.end();\n return;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- fetch response.body is not typed as node stream\n const typedBody = response.body! as unknown as import('stream/web').ReadableStream<Uint8Array>;\n const nodeStream = Readable.fromWeb(typedBody);\n nodeStream.pipe(res);\n await new Promise<void>((resolve, reject) => {\n nodeStream.once('end', resolve);\n nodeStream.once('error', reject);\n res.once('close', resolve);\n });\n } catch (err) {\n opts.requestTracker.remove(requestId);\n throw err;\n }\n}\n\nfunction readIncomingBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => {\n const buf: Buffer = chunk;\n chunks.push(buf);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nexport function flattenIncomingHeaders(\n headers: IncomingMessage['headers'],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value == null) {\n continue;\n }\n out[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : String(value);\n }\n return out;\n}\n\nexport function headersToObject(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nfunction setCorsHeaders(res: ServerResponse): void {\n const headers = corsHeaders();\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n}\n\nexport function corsHeaders(): Record<string, string> {\n return {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET,POST,OPTIONS',\n 'access-control-allow-headers':\n 'authorization,content-type,x-api-key,anthropic-version,anthropic-beta,anthropic-dangerous-direct-browser-access',\n 'access-control-expose-headers': 'content-type',\n };\n}\n\nexport function tryParseJson(str: string | undefined | null): unknown {\n if (!str) {\n return str ?? null;\n }\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n\nexport function headersInitToObject(headersInit: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!headersInit) {\n return out;\n }\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n out[String(key).toLowerCase()] = String(value);\n }\n return out;\n }\n for (const [key, value] of Object.entries(headersInit)) {\n out[key.toLowerCase()] = String(value);\n }\n return out;\n}\n\nexport function saveErrorDump(dump: {\n method: string;\n url: string;\n clientRequest: { headers: Record<string, string>; body: unknown };\n upstreamRequest?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n upstreamResponse?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n proxyResponse: { status: number; headers: Record<string, string>; body: unknown };\n}): string {\n const dir = resolve(process.cwd(), 'logs');\n mkdirSync(dir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n const status = dump.upstreamResponse?.status ?? dump.proxyResponse.status;\n const filename = `proxy-error-${ts}-${status}.json`;\n const filePath = join(dir, filename);\n const payload = {\n timestamp: new Date().toISOString(),\n ...dump,\n };\n redactAuth(payload.clientRequest?.headers);\n redactAuth(payload.upstreamRequest?.headers);\n writeFileSync(filePath, JSON.stringify(payload, null, 2));\n return filePath;\n}\n\nexport function redactAuth(headers: Record<string, string> | undefined): void {\n if (!headers) {\n return;\n }\n for (const key of Object.keys(headers)) {\n const lowerKey = key.toLowerCase();\n if (\n lowerKey === 'authorization' ||\n lowerKey === 'x-api-key' ||\n lowerKey === 'api-key' ||\n lowerKey === 'cookie'\n ) {\n headers[key] = '[REDACTED]';\n }\n }\n}\n","// ==============================================================================\n// Config Loader\n// ==============================================================================\n/**\n * Configuration file loader and validator.\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n\nconst CONFIG_FILE_NAMES = [\n 'codeproxy.config.json',\n 'codeproxy.config.js',\n 'codeproxy.config.mjs',\n 'codeproxy.config.ts',\n '.codeproxy.json',\n '.codeproxy.js',\n] as const;\n\n/**\n * Find and load a config file.\n */\nexport async function loadConfigFile(\n searchFrom: string = process.cwd(),\n): Promise<ConfigFile | null> {\n const configPath = findConfigPath(searchFrom);\n if (!configPath) {\n return null;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (configPath.endsWith('.json')) {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } else if (configPath.endsWith('.js') || configPath.endsWith('.mjs')) {\n /* c8 ignore start */\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } else if (configPath.endsWith('.ts')) {\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } /* c8 ignore stop */\n return null; /* c8 ignore next -- trailing fallback */\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n return null;\n }\n}\n\nfunction findConfigPath(searchFrom: string): string | null {\n let currentDir = searchFrom;\n const root = parseRoot(searchFrom);\n\n while (currentDir !== root && currentDir !== dirname(currentDir)) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = resolve(currentDir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n currentDir = dirname(currentDir);\n }\n\n return null;\n}\n\nfunction parseRoot(path: string): string {\n const parsed = resolve(path);\n const root = parsed.split(/[\\\\/]/)[0];\n return resolve(root);\n}\n\n/**\n * Validate the config file structure.\n */\nexport function validateConfig(config: unknown): { valid: boolean; error?: string } {\n if (typeof config !== 'object' || config === null) {\n return { valid: false, error: 'Config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = config as Record<string, unknown>;\n\n if (typeof cfg.version !== 'string') {\n return { valid: false, error: 'Config must have a version string' };\n }\n\n if (typeof cfg.currentUpstream !== 'string') {\n return { valid: false, error: 'Config must have a currentUpstream string' };\n }\n\n if (typeof cfg.upstreams !== 'object' || cfg.upstreams === null) {\n return { valid: false, error: 'Config must have an upstreams object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const upstreams: Record<string, unknown> = cfg.upstreams as Record<string, unknown>;\n\n if (!(cfg.currentUpstream in upstreams)) {\n return {\n valid: false,\n error: `currentUpstream \"${cfg.currentUpstream}\" not found in upstreams`,\n };\n }\n\n for (const [name, upstream] of Object.entries(upstreams)) {\n const result = validateUpstreamConfig(upstream);\n if (!result.valid) {\n return {\n valid: false,\n error: `Upstream \"${name}\" is invalid: ${result.error}`,\n };\n }\n }\n\n return { valid: true };\n}\n\nexport function validateUpstreamConfig(upstream: unknown): {\n valid: boolean;\n error?: string;\n} {\n if (typeof upstream !== 'object' || upstream === null) {\n return { valid: false, error: 'Upstream config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = upstream as Record<string, unknown>;\n\n if (cfg.format !== undefined) {\n if (typeof cfg.format !== 'string') {\n return { valid: false, error: 'format must be a string if provided' };\n }\n const validFormats = ['anthropic', 'openai-chat'];\n if (!validFormats.includes(cfg.format)) {\n return {\n valid: false,\n error: `Invalid format: ${cfg.format}. Must be one of: ${validFormats.join(', ')}`,\n };\n }\n }\n\n if (typeof cfg.baseUrl !== 'string') {\n return { valid: false, error: 'baseUrl is required and must be a string' };\n }\n\n if (cfg.apiVersion !== undefined && typeof cfg.apiVersion !== 'string') {\n return { valid: false, error: 'apiVersion must be a string if provided' };\n }\n\n if (cfg.apiKey !== undefined && typeof cfg.apiKey !== 'string') {\n return { valid: false, error: 'apiKey must be a string if provided' };\n }\n\n if (cfg.model !== undefined && typeof cfg.model !== 'string') {\n return { valid: false, error: 'model must be a string if provided' };\n }\n\n if (cfg.dropImages !== undefined && typeof cfg.dropImages !== 'boolean') {\n return { valid: false, error: 'dropImages must be a boolean if provided' };\n }\n\n if (cfg.fallback !== undefined && typeof cfg.fallback !== 'string') {\n return { valid: false, error: 'fallback must be a string if provided' };\n }\n\n if (cfg.headers !== undefined && (typeof cfg.headers !== 'object' || cfg.headers === null)) {\n return { valid: false, error: 'headers must be an object if provided' };\n }\n\n if (cfg.reasoningEffort !== undefined && typeof cfg.reasoningEffort !== 'string') {\n return { valid: false, error: 'reasoningEffort must be a string if provided' };\n }\n\n // thinking is optional and can be any type; no validation needed\n\n return { valid: true };\n}\n\n/**\n * Get the current upstream config from a validated config file.\n */\nexport function getCurrentUpstreamConfig(config: ConfigFile): UpstreamConfig | null {\n const upstream = config.upstreams[config.currentUpstream];\n if (!upstream) {\n return null;\n }\n return upstream;\n}\n\n// Re-export types\nexport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n","// ==============================================================================\n// Server Startup\n// ==============================================================================\n\n/**\n * `codeproxy` CLI.\n *\n * Usage:\n * npx codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n * npx codeproxy --config config.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { startProxy, type StartProxyOptions } from './proxy.js';\nimport type { UpstreamFormat } from '@codeproxy/core';\nimport { validateConfig, getCurrentUpstreamConfig, type ConfigFile } from '../utils/config.js';\n\ninterface CliArgs {\n upstreamFormat?: UpstreamFormat | string;\n config?: string;\n host?: string;\n port?: number;\n baseUrl?: string;\n apiVersion?: string;\n apikey?: string;\n model?: string;\n cors?: boolean;\n dropImages?: boolean;\n help?: boolean;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n const out: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n const take = () => argv[++i];\n switch (arg) {\n case '-h':\n case '--help':\n out.help = true;\n break;\n case '-p':\n case '--port':\n out.port = Number(take());\n break;\n case '--host':\n out.host = take();\n break;\n case '--upstream-format':\n out.upstreamFormat = take();\n break;\n case '--base-url':\n out.baseUrl = take();\n break;\n case '--config':\n out.config = take();\n break;\n case '--api-version':\n out.apiVersion = take();\n break;\n case '--apikey':\n out.apikey = take();\n break;\n case '--model':\n out.model = take();\n break;\n case '--drop-images':\n out.dropImages = true;\n break;\n case '--no-cors':\n out.cors = false;\n break;\n default:\n if (arg.startsWith('--upstream-format=')) {\n out.upstreamFormat = arg.slice('--upstream-format='.length);\n } else if (arg.startsWith('--port=')) {\n out.port = Number(arg.slice('--port='.length));\n } else if (arg.startsWith('--host=')) {\n out.host = arg.slice('--host='.length);\n } else if (arg.startsWith('--base-url=')) {\n out.baseUrl = arg.slice('--base-url='.length);\n } else if (arg.startsWith('--api-version=')) {\n out.apiVersion = arg.slice('--api-version='.length);\n } else if (arg.startsWith('--apikey=')) {\n out.apikey = arg.slice('--apikey='.length);\n } else if (arg.startsWith('--model=')) {\n out.model = arg.slice('--model='.length);\n } else if (arg.startsWith('--config=')) {\n out.config = arg.slice('--config='.length);\n } else {\n console.error(`Unknown argument: ${arg}`);\n out.help = true;\n }\n }\n }\n return out;\n}\n\nexport function printHelp(): void {\n console.log(`codeproxy - local Responses API proxy\n\nUsage:\n codeproxy --base-url <url> [options]\n codeproxy --config <file> [options]\n\nOptions:\n --base-url <url> Upstream endpoint URL (required when not using --config)\n --upstream-format <fmt> Upstream API format: anthropic | openai-chat\n (optional; inferred from --base-url when omitted:\n */messages or *anthropic* → anthropic,\n */chat/completions → openai-chat)\n --config <file> Use a config file instead of CLI flags\n --host <host> Bind host (default: 127.0.0.1)\n -p, --port <port> Bind port (default: 8787; 0 = random)\n --api-version <ver> Override anthropic-version header (anthropic only)\n --apikey <key> Override upstream Authorization: Bearer <key>\n --model <name> Override the model field in incoming requests\n --no-cors Disable CORS headers\n -h, --help Show help\n\nConfig File Mode:\n When using --config, upstream settings are loaded from the config file.\n Command-line options can override config values.\n\n Config file format (JSON):\n {\n \"version\": \"1.0\",\n \"currentUpstream\": \"my-claude\",\n \"upstreams\": {\n \"my-claude\": {\n \"baseUrl\": \"https://api.anthropic.com/v1/messages\",\n \"apiKey\": \"your-api-key\",\n \"model\": \"claude-sonnet-4-5\"\n },\n \"my-openai\": {\n \"baseUrl\": \"https://api.openai.com/v1/chat/completions\",\n \"apiKey\": \"your-openai-key\"\n }\n }\n }\n\n \"format\" is optional; inferred from baseUrl when omitted.\n\nAuth is caller-driven: send Authorization: Bearer <key> (or the upstream's\nnative header) when calling the proxy. Nothing is stored server-side.\n\nExamples:\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n codeproxy --upstream-format openai-chat --base-url https://api.openai.com/v1/chat/completions\n codeproxy --config my-config.json\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages --apikey <key>\n`);\n}\n\nexport async function loadConfigFile(configPath: string): Promise<ConfigFile> {\n if (!existsSync(configPath)) {\n console.error(`Config file not found: ${configPath}`);\n process.exit(1);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n process.exit(1);\n }\n}\n\nexport async function loadConfigAndApplyOverrides(\n configPath: string,\n overrides: CliArgs,\n): Promise<StartProxyOptions> {\n const config = await loadConfigFile(configPath);\n\n const validation = validateConfig(config);\n if (!validation.valid) {\n console.error(`Invalid config file: ${validation.error}`);\n process.exit(1);\n }\n\n const upstreamConfig = getCurrentUpstreamConfig(config);\n /* c8 ignore start */ if (!upstreamConfig) {\n console.error(`Current upstream \"${config.currentUpstream}\" not found in config`);\n process.exit(1);\n } /* c8 ignore stop */\n\n console.log(`Loaded config from: ${configPath}`);\n console.log(\n `Current upstream: ${config.currentUpstream}${upstreamConfig.format ? ` (${upstreamConfig.format})` : ''}`,\n );\n console.log(`Model: ${upstreamConfig.model || '(not set)'}`);\n const mergedEffort = upstreamConfig.reasoningEffort ?? config.reasoningEffort;\n if (mergedEffort) {\n console.log(`Reasoning effort: ${mergedEffort}`);\n }\n const mergedHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(mergedHeaders, upstreamConfig.headers);\n }\n if (mergedHeaders.authorization) {\n mergedHeaders.authorization = '\"[REDACTED]\"';\n }\n if (Object.keys(mergedHeaders).length > 0) {\n console.log(`Headers: ${JSON.stringify(mergedHeaders)}`);\n }\n // ==============================================================================\n // Proxy Launch\n // ==============================================================================\n\n const options: StartProxyOptions = {\n upstreamFormat: upstreamConfig.format,\n baseUrl: overrides.baseUrl || upstreamConfig.baseUrl,\n apiVersion: overrides.apiVersion || upstreamConfig.apiVersion,\n model: overrides.model || upstreamConfig.model,\n host: overrides.host || upstreamConfig.host,\n port:\n overrides.port !== undefined\n ? overrides.port\n : // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n (config as unknown as Record<string, unknown>).port\n ? // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n Number((config as unknown as Record<string, unknown>).port)\n : upstreamConfig.port\n ? Number(upstreamConfig.port)\n : undefined,\n timeoutMs: upstreamConfig.timeoutMs ?? config.timeoutMs,\n dropImages: upstreamConfig.dropImages,\n cors: overrides.cors,\n reasoning_effort: upstreamConfig.reasoningEffort ?? config.reasoningEffort,\n thinking: upstreamConfig.thinking ?? config.thinking,\n };\n\n const defaultHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(defaultHeaders, upstreamConfig.headers);\n }\n if (upstreamConfig.apiKey) {\n defaultHeaders.authorization = `Bearer ${upstreamConfig.apiKey}`;\n }\n if (overrides.apikey) {\n defaultHeaders.authorization = `Bearer ${overrides.apikey}`;\n }\n\n if (Object.keys(defaultHeaders).length > 0) {\n options.defaultHeaders = defaultHeaders;\n }\n\n // Resolve fallback upstream if configured\n if (upstreamConfig.fallback) {\n const fbConfig = config.upstreams[upstreamConfig.fallback];\n if (fbConfig) {\n const fbHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (fbConfig.headers) {\n Object.assign(fbHeaders, fbConfig.headers);\n }\n if (fbConfig.apiKey) {\n fbHeaders.authorization = `Bearer ${fbConfig.apiKey}`;\n }\n const fbFormat: UpstreamFormat | undefined = fbConfig.format;\n options.fallbackUpstream = {\n baseUrl: fbConfig.baseUrl,\n upstreamFormat: fbFormat,\n model: fbConfig.model ?? options.model,\n defaultHeaders: Object.keys(fbHeaders).length > 0 ? fbHeaders : undefined,\n apiVersion: fbConfig.apiVersion ?? options.apiVersion,\n reasoning_effort: fbConfig.reasoningEffort ?? options.reasoning_effort,\n thinking: fbConfig.thinking ?? options.thinking,\n };\n console.log(\n `Fallback upstream: ${upstreamConfig.fallback}${fbConfig.model ? ` (${fbConfig.model})` : ''}`,\n );\n } else {\n console.warn(`Warning: fallback upstream \"${upstreamConfig.fallback}\" not found in config`);\n }\n }\n\n return options;\n}\n\n/* c8 ignore next -- main is entry point */\nexport async function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n\n if (args.help) {\n printHelp();\n process.exit(0);\n }\n\n let options: StartProxyOptions;\n\n if (args.config) {\n options = await loadConfigAndApplyOverrides(args.config, args);\n } else if (args.baseUrl) {\n // eslint-disable-next-line no-restricted-syntax -- parsed string may not match union type\n const upstreamFormat = args.upstreamFormat as UpstreamFormat | undefined;\n options = {\n upstreamFormat,\n baseUrl: args.baseUrl,\n host: args.host,\n port: args.port,\n apiVersion: args.apiVersion,\n model: args.model,\n defaultHeaders: args.apikey ? { authorization: `Bearer ${args.apikey}` } : undefined,\n dropImages: args.dropImages,\n cors: args.cors,\n };\n } else {\n console.error('Error: Either --config <file> or --base-url <url> is required');\n console.error('');\n printHelp();\n process.exit(1);\n }\n\n const proxy = await startProxy(options);\n /* c8 ignore start */\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await proxy.close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n /* c8 ignore stop */\n}\n\n/* c8 ignore start */\nif (process.argv[1]?.endsWith('cli.js') || process.argv[1]?.endsWith('cli.ts') || process.argv[1]?.endsWith('codeproxy')) {\n void main();\n}\n/* c8 ignore stop */\n"]}
package/dist/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
2
3
  import http from 'http';
3
4
  import { Readable } from 'stream';
@@ -763,7 +764,7 @@ Received ${signal}, shutting down...`);
763
764
  process.on("SIGINT", () => void shutdown("SIGINT"));
764
765
  process.on("SIGTERM", () => void shutdown("SIGTERM"));
765
766
  }
766
- if (process.argv[1]?.endsWith("cli.js") || process.argv[1]?.endsWith("cli.ts")) {
767
+ if (process.argv[1]?.endsWith("cli.js") || process.argv[1]?.endsWith("cli.ts") || process.argv[1]?.endsWith("codeproxy")) {
767
768
  void main();
768
769
  }
769
770
 
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/proxy.ts","../src/utils/config.ts","../src/server/cli.ts"],"names":["resolve","existsSync","readFileSync"],"mappings":"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","file":"cli.js","sourcesContent":["// ==============================================================================\n// Helpers\n// ==============================================================================\n\n/**\n * Local HTTP proxy that exposes the Responses API and forwards translated\n * requests to the configured upstream API format.\n */\n\nimport http, { type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport { Readable } from 'node:stream';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\n// ==============================================================================\n// Helpers\n// ==============================================================================\nexport function fmtTime(date: Date): string {\n return date.toLocaleTimeString('en-US', { hour12: false });\n}\n\nexport function fmtDuration(ms: number): string {\n // ==============================================================================\n // Server\n // ==============================================================================\n\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\nimport { createResponsesFetch, type CreateResponsesFetchOptions } from '@codeproxy/core';\n\nexport interface StartProxyOptions extends Omit<CreateResponsesFetchOptions, 'passthroughFetch'> {\n /** Host to bind to. Defaults to `127.0.0.1`. */\n host?: string;\n /** Port to listen on. Defaults to `8787`; pass `0` for a random free port. */\n port?: number;\n /** Enable permissive CORS (useful for local browser dev). Defaults to true. */\n cors?: boolean;\n /** Optional logger. Defaults to `console`. Pass `null` to silence. */\n logger?: Pick<Console, 'log' | 'warn' | 'error'> | null;\n /** Optional callback to receive cache statistics after each request completes. */\n onCacheStats?: (stats: {\n cachedTokens: number;\n cacheCreationTokens: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n method?: string;\n url?: string;\n durationMs?: number;\n }) => void;\n}\n\nexport interface RunningProxy {\n host: string;\n port: number;\n url: string;\n server: Server;\n close: () => Promise<void>;\n}\n\nexport async function startProxy(options: StartProxyOptions): Promise<RunningProxy> {\n const host = options.host ?? '127.0.0.1';\n const port = options.port ?? 8787;\n const cors = options.cors ?? true;\n const logger = options.logger === null ? null : (options.logger ?? console);\n\n // Rolling average for request duration coloring (last 50 requests)\n const durationHistory: number[] = [];\n function updateRollingAverage(ms: number) {\n durationHistory.push(ms); /* c8 ignore next 3 -- threshold rarely hit */\n if (durationHistory.length > 50) {\n durationHistory.shift();\n }\n return durationHistory.reduce((sum, val) => sum + val, 0) / durationHistory.length;\n }\n\n // Centralized status line for all active requests\n const activeRequests = new Map<string, { method: string; url: string; startTime: number }>();\n // ==============================================================================\n // Request Handler\n // ==============================================================================\n\n let statusTimerId: ReturnType<typeof setInterval> | null = null;\n\n function drawStatusLine() {\n if (activeRequests.size === 0) {\n return; /* c8 ignore next -- empty guard */\n }\n const parts = Array.from(activeRequests.entries()).map(([, req]) => {\n const elapsed = Date.now() - req.startTime;\n return `[${fmtDuration(elapsed)}]`;\n });\n process.stdout.write(`\\r\\x1b[K⏳ ${parts.join(', ')}`);\n }\n\n const requestTracker = {\n add(method: string, url: string): string {\n const id = `${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;\n activeRequests.set(id, { method, url, startTime: Date.now() });\n drawStatusLine();\n if (!statusTimerId) {\n statusTimerId = setInterval(drawStatusLine, 150);\n }\n return id;\n },\n remove(id: string) {\n activeRequests.delete(id);\n if (activeRequests.size === 0) {\n process.stdout.write('\\r\\x1b[K');\n if (statusTimerId) {\n clearInterval(statusTimerId);\n statusTimerId = null;\n }\n }\n },\n };\n\n const requestInfo = { method: '', url: '', startTime: 0, resultLog: '' };\n\n const upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n } = {};\n\n const baseFetch = options.fetch ?? globalThis.fetch;\n const capturingFetch: typeof fetch = async (input, init) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? input?.method ?? 'GET').toUpperCase();\n const reqHeaders = headersInitToObject(init?.headers);\n let reqBody: unknown = undefined;\n if (init?.body != null) {\n if (typeof init.body === 'string') {\n reqBody = tryParseJson(init.body);\n } /* c8 ignore next 6 -- defensive body serialization */ else if (\n init.body instanceof ArrayBuffer\n ) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else if (ArrayBuffer.isView(init.body)) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else {\n reqBody = String(init.body);\n }\n }\n upstreamCapture.request = { url, method, headers: reqHeaders, body: reqBody };\n\n const resp = await baseFetch(input, init);\n\n if (!resp.ok) {\n const clone = resp.clone();\n const text = await clone.text().catch(() => '');\n upstreamCapture.response = {\n status: resp.status,\n statusText: resp.statusText,\n headers: headersToObject(resp.headers),\n body: tryParseJson(text),\n };\n } else {\n upstreamCapture.response = undefined;\n }\n return resp;\n };\n\n const apiFetch = createResponsesFetch({\n upstreamFormat: options.upstreamFormat,\n baseUrl: options.baseUrl,\n apiVersion: options.apiVersion,\n model: options.model,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n dropImages: options.dropImages,\n fallbackUpstream: options.fallbackUpstream,\n fetch: capturingFetch,\n passthroughFetch: async () =>\n new Response(JSON.stringify({ error: { message: 'Not found' } }), {\n status: 404,\n headers: { 'content-type': 'application/json' },\n }),\n onCacheStats: (stats) => {\n const durationMs = requestInfo.startTime ? Date.now() - requestInfo.startTime : 0;\n const billedTokens = stats.inputTokens + stats.outputTokens - stats.cachedTokens;\n const parts = [\n `total=${stats.totalTokens}`,\n `input=${stats.inputTokens}`,\n `output=${stats.outputTokens}`,\n `cached=${stats.cachedTokens}`,\n `billed=${billedTokens}`,\n ];\n if (stats.cacheCreationTokens > 0) {\n parts.push(`cache_creation=${stats.cacheCreationTokens}`);\n }\n const avg = updateRollingAverage(durationMs);\n const ratio = avg > 0 ? durationMs / avg : 1;\n const color = ratio < 0.8 ? '\\x1b[32m' : ratio < 1.5 ? '\\x1b[33m' : '\\x1b[31m';\n const reset = '\\x1b[0m';\n const logMsg = `[${fmtTime(new Date())}] -> 200 (${color}${fmtDuration(durationMs)}${reset} avg=${fmtDuration(Math.round(avg))}) [${parts.join(', ')}]`;\n requestInfo.resultLog =\n stats.cachedTokens < 1024 && billedTokens > 0 ? `⚠️ NO CACHE -- ${logMsg}` : logMsg;\n\n if (options.onCacheStats) {\n options.onCacheStats({\n ...stats,\n method: requestInfo.method || undefined,\n url: requestInfo.url || undefined,\n durationMs: durationMs || undefined,\n });\n }\n },\n });\n\n const server = http.createServer(async (req, res) => {\n const start = Date.now();\n requestInfo.method = req.method ?? 'POST';\n requestInfo.url = req.url ?? '/v1/responses';\n requestInfo.startTime = start;\n\n const abortController = new AbortController();\n const timeoutMs = options.timeoutMs;\n let timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n if (timeoutMs && timeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n logger?.warn(`[timeout] request exceeded ${timeoutMs}ms, aborting`);\n abortController.abort();\n res.destroy();\n req.destroy();\n }, timeoutMs);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await handleRequest(req, res, {\n apiFetch,\n cors,\n logger,\n method: req.method ?? 'POST',\n url: req.url ?? '/',\n upstreamCapture,\n requestInfo,\n requestTracker,\n signal: abortController.signal,\n });\n } catch (err) {\n logger?.error('[proxy-error]', err);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: 'Internal server error' } }));\n }\n /* c8 ignore start */\n } catch {\n // ignore\n } /* c8 ignore stop */\n } finally {\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n }\n }\n });\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n const actualPort = (() => {\n // eslint-disable-next-line no-restricted-syntax -- net.Server.address() returns string | AddressInfo | null\n const addr = server.address() as { port: number } | null;\n return addr.port;\n })();\n const url = `http://${host}:${actualPort}`;\n logger?.log(`Proxy listening on ${url}`);\n logger?.log(`Upstream format: ${options.upstreamFormat}`);\n logger?.log(`Upstream URL: ${options.baseUrl}`);\n resolve({\n host,\n port: actualPort,\n url,\n server,\n close: () =>\n new Promise((res) => {\n server.close((err) => {\n /* c8 ignore start */\n if (err) {\n logger?.warn('Error closing server:', err);\n }\n /* c8 ignore stop */\n res();\n });\n }),\n });\n });\n server.once('error', reject);\n });\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n opts: {\n apiFetch: typeof fetch;\n cors: boolean;\n logger: Pick<Console, 'log' | 'warn' | 'error'> | null;\n method: string;\n url: string;\n upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n };\n requestInfo: { resultLog: string };\n requestTracker: { add: (method: string, url: string) => string; remove: (id: string) => void };\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (opts.cors) {\n setCorsHeaders(res);\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const method = req.method ?? 'GET';\n const urlPath = req.url ?? '/';\n const headers = flattenIncomingHeaders(req.headers);\n\n let body: Buffer | undefined;\n if (method !== 'GET' && method !== 'HEAD') {\n body = await readIncomingBody(req);\n }\n\n if (!/^\\/v1\\/responses\\/?(?:\\?|$)/.test(urlPath)) {\n res.writeHead(404, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: `Not found: ${method} ${urlPath}` } }));\n return;\n }\n\n const requestBodyText = body ? body.toString('utf8') : undefined;\n\n const requestStart = Date.now();\n const requestId = opts.requestTracker.add(method, urlPath);\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const response = await opts.apiFetch(`http://local${urlPath}`, {\n method,\n headers,\n body: body ? new Uint8Array(body) : undefined,\n signal: opts.signal,\n });\n\n // Consume response body so onCacheStats fires (for streaming responses)\n const responseBodyText = response.body ? await response.clone().text() : '';\n\n // Remove from active requests and write final result\n opts.requestTracker.remove(requestId);\n /* c8 ignore start */\n if (opts.logger) {\n if (response.status >= 400) {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n } else if (opts.requestInfo.resultLog) {\n process.stdout.write(`\\r\\x1b[K${opts.requestInfo.resultLog}\\n`);\n } else {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n }\n }\n /* c8 ignore stop */\n if (response.status >= 400) {\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const filePath = saveErrorDump({\n method: opts.method,\n url: opts.url,\n clientRequest: {\n headers,\n body: tryParseJson(requestBodyText ?? ''),\n },\n upstreamRequest: opts.upstreamCapture.request,\n upstreamResponse: opts.upstreamCapture.response,\n proxyResponse: {\n status: response.status,\n headers: headersToObject(response.headers),\n body: tryParseJson(responseBodyText),\n },\n });\n opts.logger?.error(`[proxy-failure] full exchange saved to ${filePath}`);\n } catch (dumpErr) {\n opts.logger?.error('[proxy-failure] failed to persist error dump', dumpErr);\n }\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n if (opts.cors) {\n Object.assign(outHeaders, corsHeaders());\n }\n\n res.writeHead(response.status, outHeaders);\n\n /* c8 ignore next 3 */\n if (!response.body) {\n res.end();\n return;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- fetch response.body is not typed as node stream\n const typedBody = response.body! as unknown as import('stream/web').ReadableStream<Uint8Array>;\n const nodeStream = Readable.fromWeb(typedBody);\n nodeStream.pipe(res);\n await new Promise<void>((resolve, reject) => {\n nodeStream.once('end', resolve);\n nodeStream.once('error', reject);\n res.once('close', resolve);\n });\n } catch (err) {\n opts.requestTracker.remove(requestId);\n throw err;\n }\n}\n\nfunction readIncomingBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => {\n const buf: Buffer = chunk;\n chunks.push(buf);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nexport function flattenIncomingHeaders(\n headers: IncomingMessage['headers'],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value == null) {\n continue;\n }\n out[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : String(value);\n }\n return out;\n}\n\nexport function headersToObject(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nfunction setCorsHeaders(res: ServerResponse): void {\n const headers = corsHeaders();\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n}\n\nexport function corsHeaders(): Record<string, string> {\n return {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET,POST,OPTIONS',\n 'access-control-allow-headers':\n 'authorization,content-type,x-api-key,anthropic-version,anthropic-beta,anthropic-dangerous-direct-browser-access',\n 'access-control-expose-headers': 'content-type',\n };\n}\n\nexport function tryParseJson(str: string | undefined | null): unknown {\n if (!str) {\n return str ?? null;\n }\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n\nexport function headersInitToObject(headersInit: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!headersInit) {\n return out;\n }\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n out[String(key).toLowerCase()] = String(value);\n }\n return out;\n }\n for (const [key, value] of Object.entries(headersInit)) {\n out[key.toLowerCase()] = String(value);\n }\n return out;\n}\n\nexport function saveErrorDump(dump: {\n method: string;\n url: string;\n clientRequest: { headers: Record<string, string>; body: unknown };\n upstreamRequest?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n upstreamResponse?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n proxyResponse: { status: number; headers: Record<string, string>; body: unknown };\n}): string {\n const dir = resolve(process.cwd(), 'logs');\n mkdirSync(dir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n const status = dump.upstreamResponse?.status ?? dump.proxyResponse.status;\n const filename = `proxy-error-${ts}-${status}.json`;\n const filePath = join(dir, filename);\n const payload = {\n timestamp: new Date().toISOString(),\n ...dump,\n };\n redactAuth(payload.clientRequest?.headers);\n redactAuth(payload.upstreamRequest?.headers);\n writeFileSync(filePath, JSON.stringify(payload, null, 2));\n return filePath;\n}\n\nexport function redactAuth(headers: Record<string, string> | undefined): void {\n if (!headers) {\n return;\n }\n for (const key of Object.keys(headers)) {\n const lowerKey = key.toLowerCase();\n if (\n lowerKey === 'authorization' ||\n lowerKey === 'x-api-key' ||\n lowerKey === 'api-key' ||\n lowerKey === 'cookie'\n ) {\n headers[key] = '[REDACTED]';\n }\n }\n}\n","// ==============================================================================\n// Config Loader\n// ==============================================================================\n/**\n * Configuration file loader and validator.\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n\nconst CONFIG_FILE_NAMES = [\n 'codeproxy.config.json',\n 'codeproxy.config.js',\n 'codeproxy.config.mjs',\n 'codeproxy.config.ts',\n '.codeproxy.json',\n '.codeproxy.js',\n] as const;\n\n/**\n * Find and load a config file.\n */\nexport async function loadConfigFile(\n searchFrom: string = process.cwd(),\n): Promise<ConfigFile | null> {\n const configPath = findConfigPath(searchFrom);\n if (!configPath) {\n return null;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (configPath.endsWith('.json')) {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } else if (configPath.endsWith('.js') || configPath.endsWith('.mjs')) {\n /* c8 ignore start */\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } else if (configPath.endsWith('.ts')) {\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } /* c8 ignore stop */\n return null; /* c8 ignore next -- trailing fallback */\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n return null;\n }\n}\n\nfunction findConfigPath(searchFrom: string): string | null {\n let currentDir = searchFrom;\n const root = parseRoot(searchFrom);\n\n while (currentDir !== root && currentDir !== dirname(currentDir)) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = resolve(currentDir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n currentDir = dirname(currentDir);\n }\n\n return null;\n}\n\nfunction parseRoot(path: string): string {\n const parsed = resolve(path);\n const root = parsed.split(/[\\\\/]/)[0];\n return resolve(root);\n}\n\n/**\n * Validate the config file structure.\n */\nexport function validateConfig(config: unknown): { valid: boolean; error?: string } {\n if (typeof config !== 'object' || config === null) {\n return { valid: false, error: 'Config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = config as Record<string, unknown>;\n\n if (typeof cfg.version !== 'string') {\n return { valid: false, error: 'Config must have a version string' };\n }\n\n if (typeof cfg.currentUpstream !== 'string') {\n return { valid: false, error: 'Config must have a currentUpstream string' };\n }\n\n if (typeof cfg.upstreams !== 'object' || cfg.upstreams === null) {\n return { valid: false, error: 'Config must have an upstreams object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const upstreams: Record<string, unknown> = cfg.upstreams as Record<string, unknown>;\n\n if (!(cfg.currentUpstream in upstreams)) {\n return {\n valid: false,\n error: `currentUpstream \"${cfg.currentUpstream}\" not found in upstreams`,\n };\n }\n\n for (const [name, upstream] of Object.entries(upstreams)) {\n const result = validateUpstreamConfig(upstream);\n if (!result.valid) {\n return {\n valid: false,\n error: `Upstream \"${name}\" is invalid: ${result.error}`,\n };\n }\n }\n\n return { valid: true };\n}\n\nexport function validateUpstreamConfig(upstream: unknown): {\n valid: boolean;\n error?: string;\n} {\n if (typeof upstream !== 'object' || upstream === null) {\n return { valid: false, error: 'Upstream config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = upstream as Record<string, unknown>;\n\n if (cfg.format !== undefined) {\n if (typeof cfg.format !== 'string') {\n return { valid: false, error: 'format must be a string if provided' };\n }\n const validFormats = ['anthropic', 'openai-chat'];\n if (!validFormats.includes(cfg.format)) {\n return {\n valid: false,\n error: `Invalid format: ${cfg.format}. Must be one of: ${validFormats.join(', ')}`,\n };\n }\n }\n\n if (typeof cfg.baseUrl !== 'string') {\n return { valid: false, error: 'baseUrl is required and must be a string' };\n }\n\n if (cfg.apiVersion !== undefined && typeof cfg.apiVersion !== 'string') {\n return { valid: false, error: 'apiVersion must be a string if provided' };\n }\n\n if (cfg.apiKey !== undefined && typeof cfg.apiKey !== 'string') {\n return { valid: false, error: 'apiKey must be a string if provided' };\n }\n\n if (cfg.model !== undefined && typeof cfg.model !== 'string') {\n return { valid: false, error: 'model must be a string if provided' };\n }\n\n if (cfg.dropImages !== undefined && typeof cfg.dropImages !== 'boolean') {\n return { valid: false, error: 'dropImages must be a boolean if provided' };\n }\n\n if (cfg.fallback !== undefined && typeof cfg.fallback !== 'string') {\n return { valid: false, error: 'fallback must be a string if provided' };\n }\n\n if (cfg.headers !== undefined && (typeof cfg.headers !== 'object' || cfg.headers === null)) {\n return { valid: false, error: 'headers must be an object if provided' };\n }\n\n if (cfg.reasoningEffort !== undefined && typeof cfg.reasoningEffort !== 'string') {\n return { valid: false, error: 'reasoningEffort must be a string if provided' };\n }\n\n // thinking is optional and can be any type; no validation needed\n\n return { valid: true };\n}\n\n/**\n * Get the current upstream config from a validated config file.\n */\nexport function getCurrentUpstreamConfig(config: ConfigFile): UpstreamConfig | null {\n const upstream = config.upstreams[config.currentUpstream];\n if (!upstream) {\n return null;\n }\n return upstream;\n}\n\n// Re-export types\nexport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n","// ==============================================================================\n// Server Startup\n// ==============================================================================\n\n/**\n * `codeproxy` CLI.\n *\n * Usage:\n * npx codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n * npx codeproxy --config config.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { startProxy, type StartProxyOptions } from './proxy.js';\nimport type { UpstreamFormat } from '@codeproxy/core';\nimport { validateConfig, getCurrentUpstreamConfig, type ConfigFile } from '../utils/config.js';\n\ninterface CliArgs {\n upstreamFormat?: UpstreamFormat | string;\n config?: string;\n host?: string;\n port?: number;\n baseUrl?: string;\n apiVersion?: string;\n apikey?: string;\n model?: string;\n cors?: boolean;\n dropImages?: boolean;\n help?: boolean;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n const out: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n const take = () => argv[++i];\n switch (arg) {\n case '-h':\n case '--help':\n out.help = true;\n break;\n case '-p':\n case '--port':\n out.port = Number(take());\n break;\n case '--host':\n out.host = take();\n break;\n case '--upstream-format':\n out.upstreamFormat = take();\n break;\n case '--base-url':\n out.baseUrl = take();\n break;\n case '--config':\n out.config = take();\n break;\n case '--api-version':\n out.apiVersion = take();\n break;\n case '--apikey':\n out.apikey = take();\n break;\n case '--model':\n out.model = take();\n break;\n case '--drop-images':\n out.dropImages = true;\n break;\n case '--no-cors':\n out.cors = false;\n break;\n default:\n if (arg.startsWith('--upstream-format=')) {\n out.upstreamFormat = arg.slice('--upstream-format='.length);\n } else if (arg.startsWith('--port=')) {\n out.port = Number(arg.slice('--port='.length));\n } else if (arg.startsWith('--host=')) {\n out.host = arg.slice('--host='.length);\n } else if (arg.startsWith('--base-url=')) {\n out.baseUrl = arg.slice('--base-url='.length);\n } else if (arg.startsWith('--api-version=')) {\n out.apiVersion = arg.slice('--api-version='.length);\n } else if (arg.startsWith('--apikey=')) {\n out.apikey = arg.slice('--apikey='.length);\n } else if (arg.startsWith('--model=')) {\n out.model = arg.slice('--model='.length);\n } else if (arg.startsWith('--config=')) {\n out.config = arg.slice('--config='.length);\n } else {\n console.error(`Unknown argument: ${arg}`);\n out.help = true;\n }\n }\n }\n return out;\n}\n\nexport function printHelp(): void {\n console.log(`codeproxy - local Responses API proxy\n\nUsage:\n codeproxy --base-url <url> [options]\n codeproxy --config <file> [options]\n\nOptions:\n --base-url <url> Upstream endpoint URL (required when not using --config)\n --upstream-format <fmt> Upstream API format: anthropic | openai-chat\n (optional; inferred from --base-url when omitted:\n */messages or *anthropic* → anthropic,\n */chat/completions → openai-chat)\n --config <file> Use a config file instead of CLI flags\n --host <host> Bind host (default: 127.0.0.1)\n -p, --port <port> Bind port (default: 8787; 0 = random)\n --api-version <ver> Override anthropic-version header (anthropic only)\n --apikey <key> Override upstream Authorization: Bearer <key>\n --model <name> Override the model field in incoming requests\n --no-cors Disable CORS headers\n -h, --help Show help\n\nConfig File Mode:\n When using --config, upstream settings are loaded from the config file.\n Command-line options can override config values.\n\n Config file format (JSON):\n {\n \"version\": \"1.0\",\n \"currentUpstream\": \"my-claude\",\n \"upstreams\": {\n \"my-claude\": {\n \"baseUrl\": \"https://api.anthropic.com/v1/messages\",\n \"apiKey\": \"your-api-key\",\n \"model\": \"claude-sonnet-4-5\"\n },\n \"my-openai\": {\n \"baseUrl\": \"https://api.openai.com/v1/chat/completions\",\n \"apiKey\": \"your-openai-key\"\n }\n }\n }\n\n \"format\" is optional; inferred from baseUrl when omitted.\n\nAuth is caller-driven: send Authorization: Bearer <key> (or the upstream's\nnative header) when calling the proxy. Nothing is stored server-side.\n\nExamples:\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n codeproxy --upstream-format openai-chat --base-url https://api.openai.com/v1/chat/completions\n codeproxy --config my-config.json\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages --apikey <key>\n`);\n}\n\nexport async function loadConfigFile(configPath: string): Promise<ConfigFile> {\n if (!existsSync(configPath)) {\n console.error(`Config file not found: ${configPath}`);\n process.exit(1);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n process.exit(1);\n }\n}\n\nexport async function loadConfigAndApplyOverrides(\n configPath: string,\n overrides: CliArgs,\n): Promise<StartProxyOptions> {\n const config = await loadConfigFile(configPath);\n\n const validation = validateConfig(config);\n if (!validation.valid) {\n console.error(`Invalid config file: ${validation.error}`);\n process.exit(1);\n }\n\n const upstreamConfig = getCurrentUpstreamConfig(config);\n /* c8 ignore start */ if (!upstreamConfig) {\n console.error(`Current upstream \"${config.currentUpstream}\" not found in config`);\n process.exit(1);\n } /* c8 ignore stop */\n\n console.log(`Loaded config from: ${configPath}`);\n console.log(\n `Current upstream: ${config.currentUpstream}${upstreamConfig.format ? ` (${upstreamConfig.format})` : ''}`,\n );\n console.log(`Model: ${upstreamConfig.model || '(not set)'}`);\n const mergedEffort = upstreamConfig.reasoningEffort ?? config.reasoningEffort;\n if (mergedEffort) {\n console.log(`Reasoning effort: ${mergedEffort}`);\n }\n const mergedHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(mergedHeaders, upstreamConfig.headers);\n }\n if (mergedHeaders.authorization) {\n mergedHeaders.authorization = '\"[REDACTED]\"';\n }\n if (Object.keys(mergedHeaders).length > 0) {\n console.log(`Headers: ${JSON.stringify(mergedHeaders)}`);\n }\n // ==============================================================================\n // Proxy Launch\n // ==============================================================================\n\n const options: StartProxyOptions = {\n upstreamFormat: upstreamConfig.format,\n baseUrl: overrides.baseUrl || upstreamConfig.baseUrl,\n apiVersion: overrides.apiVersion || upstreamConfig.apiVersion,\n model: overrides.model || upstreamConfig.model,\n host: overrides.host || upstreamConfig.host,\n port:\n overrides.port !== undefined\n ? overrides.port\n : // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n (config as unknown as Record<string, unknown>).port\n ? // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n Number((config as unknown as Record<string, unknown>).port)\n : upstreamConfig.port\n ? Number(upstreamConfig.port)\n : undefined,\n timeoutMs: upstreamConfig.timeoutMs ?? config.timeoutMs,\n dropImages: upstreamConfig.dropImages,\n cors: overrides.cors,\n reasoning_effort: upstreamConfig.reasoningEffort ?? config.reasoningEffort,\n thinking: upstreamConfig.thinking ?? config.thinking,\n };\n\n const defaultHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(defaultHeaders, upstreamConfig.headers);\n }\n if (upstreamConfig.apiKey) {\n defaultHeaders.authorization = `Bearer ${upstreamConfig.apiKey}`;\n }\n if (overrides.apikey) {\n defaultHeaders.authorization = `Bearer ${overrides.apikey}`;\n }\n\n if (Object.keys(defaultHeaders).length > 0) {\n options.defaultHeaders = defaultHeaders;\n }\n\n // Resolve fallback upstream if configured\n if (upstreamConfig.fallback) {\n const fbConfig = config.upstreams[upstreamConfig.fallback];\n if (fbConfig) {\n const fbHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (fbConfig.headers) {\n Object.assign(fbHeaders, fbConfig.headers);\n }\n if (fbConfig.apiKey) {\n fbHeaders.authorization = `Bearer ${fbConfig.apiKey}`;\n }\n const fbFormat: UpstreamFormat | undefined = fbConfig.format;\n options.fallbackUpstream = {\n baseUrl: fbConfig.baseUrl,\n upstreamFormat: fbFormat,\n model: fbConfig.model ?? options.model,\n defaultHeaders: Object.keys(fbHeaders).length > 0 ? fbHeaders : undefined,\n apiVersion: fbConfig.apiVersion ?? options.apiVersion,\n reasoning_effort: fbConfig.reasoningEffort ?? options.reasoning_effort,\n thinking: fbConfig.thinking ?? options.thinking,\n };\n console.log(\n `Fallback upstream: ${upstreamConfig.fallback}${fbConfig.model ? ` (${fbConfig.model})` : ''}`,\n );\n } else {\n console.warn(`Warning: fallback upstream \"${upstreamConfig.fallback}\" not found in config`);\n }\n }\n\n return options;\n}\n\n/* c8 ignore next -- main is entry point */\nexport async function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n\n if (args.help) {\n printHelp();\n process.exit(0);\n }\n\n let options: StartProxyOptions;\n\n if (args.config) {\n options = await loadConfigAndApplyOverrides(args.config, args);\n } else if (args.baseUrl) {\n // eslint-disable-next-line no-restricted-syntax -- parsed string may not match union type\n const upstreamFormat = args.upstreamFormat as UpstreamFormat | undefined;\n options = {\n upstreamFormat,\n baseUrl: args.baseUrl,\n host: args.host,\n port: args.port,\n apiVersion: args.apiVersion,\n model: args.model,\n defaultHeaders: args.apikey ? { authorization: `Bearer ${args.apikey}` } : undefined,\n dropImages: args.dropImages,\n cors: args.cors,\n };\n } else {\n console.error('Error: Either --config <file> or --base-url <url> is required');\n console.error('');\n printHelp();\n process.exit(1);\n }\n\n const proxy = await startProxy(options);\n /* c8 ignore start */\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await proxy.close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n /* c8 ignore stop */\n}\n\n/* c8 ignore start */\nif (process.argv[1]?.endsWith('cli.js') || process.argv[1]?.endsWith('cli.ts')) {\n void main();\n}\n/* c8 ignore stop */\n"]}
1
+ {"version":3,"sources":["../src/server/proxy.ts","../src/utils/config.ts","../src/server/cli.ts"],"names":["resolve","existsSync","readFileSync"],"mappings":"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","file":"cli.js","sourcesContent":["// ==============================================================================\n// Helpers\n// ==============================================================================\n\n/**\n * Local HTTP proxy that exposes the Responses API and forwards translated\n * requests to the configured upstream API format.\n */\n\nimport http, { type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport { Readable } from 'node:stream';\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\n// ==============================================================================\n// Helpers\n// ==============================================================================\nexport function fmtTime(date: Date): string {\n return date.toLocaleTimeString('en-US', { hour12: false });\n}\n\nexport function fmtDuration(ms: number): string {\n // ==============================================================================\n // Server\n // ==============================================================================\n\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = Math.round((ms % 60000) / 1000);\n return `${minutes}:${String(seconds).padStart(2, '0')}`;\n}\nimport { createResponsesFetch, type CreateResponsesFetchOptions } from '@codeproxy/core';\n\nexport interface StartProxyOptions extends Omit<CreateResponsesFetchOptions, 'passthroughFetch'> {\n /** Host to bind to. Defaults to `127.0.0.1`. */\n host?: string;\n /** Port to listen on. Defaults to `8787`; pass `0` for a random free port. */\n port?: number;\n /** Enable permissive CORS (useful for local browser dev). Defaults to true. */\n cors?: boolean;\n /** Optional logger. Defaults to `console`. Pass `null` to silence. */\n logger?: Pick<Console, 'log' | 'warn' | 'error'> | null;\n /** Optional callback to receive cache statistics after each request completes. */\n onCacheStats?: (stats: {\n cachedTokens: number;\n cacheCreationTokens: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n method?: string;\n url?: string;\n durationMs?: number;\n }) => void;\n}\n\nexport interface RunningProxy {\n host: string;\n port: number;\n url: string;\n server: Server;\n close: () => Promise<void>;\n}\n\nexport async function startProxy(options: StartProxyOptions): Promise<RunningProxy> {\n const host = options.host ?? '127.0.0.1';\n const port = options.port ?? 8787;\n const cors = options.cors ?? true;\n const logger = options.logger === null ? null : (options.logger ?? console);\n\n // Rolling average for request duration coloring (last 50 requests)\n const durationHistory: number[] = [];\n function updateRollingAverage(ms: number) {\n durationHistory.push(ms); /* c8 ignore next 3 -- threshold rarely hit */\n if (durationHistory.length > 50) {\n durationHistory.shift();\n }\n return durationHistory.reduce((sum, val) => sum + val, 0) / durationHistory.length;\n }\n\n // Centralized status line for all active requests\n const activeRequests = new Map<string, { method: string; url: string; startTime: number }>();\n // ==============================================================================\n // Request Handler\n // ==============================================================================\n\n let statusTimerId: ReturnType<typeof setInterval> | null = null;\n\n function drawStatusLine() {\n if (activeRequests.size === 0) {\n return; /* c8 ignore next -- empty guard */\n }\n const parts = Array.from(activeRequests.entries()).map(([, req]) => {\n const elapsed = Date.now() - req.startTime;\n return `[${fmtDuration(elapsed)}]`;\n });\n process.stdout.write(`\\r\\x1b[K⏳ ${parts.join(', ')}`);\n }\n\n const requestTracker = {\n add(method: string, url: string): string {\n const id = `${Date.now()}:${Math.random().toString(36).slice(2, 8)}`;\n activeRequests.set(id, { method, url, startTime: Date.now() });\n drawStatusLine();\n if (!statusTimerId) {\n statusTimerId = setInterval(drawStatusLine, 150);\n }\n return id;\n },\n remove(id: string) {\n activeRequests.delete(id);\n if (activeRequests.size === 0) {\n process.stdout.write('\\r\\x1b[K');\n if (statusTimerId) {\n clearInterval(statusTimerId);\n statusTimerId = null;\n }\n }\n },\n };\n\n const requestInfo = { method: '', url: '', startTime: 0, resultLog: '' };\n\n const upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n } = {};\n\n const baseFetch = options.fetch ?? globalThis.fetch;\n const capturingFetch: typeof fetch = async (input, init) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n const method = (init?.method ?? input?.method ?? 'GET').toUpperCase();\n const reqHeaders = headersInitToObject(init?.headers);\n let reqBody: unknown = undefined;\n if (init?.body != null) {\n if (typeof init.body === 'string') {\n reqBody = tryParseJson(init.body);\n } /* c8 ignore next 6 -- defensive body serialization */ else if (\n init.body instanceof ArrayBuffer\n ) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else if (ArrayBuffer.isView(init.body)) {\n reqBody = tryParseJson(new TextDecoder().decode(init.body));\n } else {\n reqBody = String(init.body);\n }\n }\n upstreamCapture.request = { url, method, headers: reqHeaders, body: reqBody };\n\n const resp = await baseFetch(input, init);\n\n if (!resp.ok) {\n const clone = resp.clone();\n const text = await clone.text().catch(() => '');\n upstreamCapture.response = {\n status: resp.status,\n statusText: resp.statusText,\n headers: headersToObject(resp.headers),\n body: tryParseJson(text),\n };\n } else {\n upstreamCapture.response = undefined;\n }\n return resp;\n };\n\n const apiFetch = createResponsesFetch({\n upstreamFormat: options.upstreamFormat,\n baseUrl: options.baseUrl,\n apiVersion: options.apiVersion,\n model: options.model,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n dropImages: options.dropImages,\n fallbackUpstream: options.fallbackUpstream,\n fetch: capturingFetch,\n passthroughFetch: async () =>\n new Response(JSON.stringify({ error: { message: 'Not found' } }), {\n status: 404,\n headers: { 'content-type': 'application/json' },\n }),\n onCacheStats: (stats) => {\n const durationMs = requestInfo.startTime ? Date.now() - requestInfo.startTime : 0;\n const billedTokens = stats.inputTokens + stats.outputTokens - stats.cachedTokens;\n const parts = [\n `total=${stats.totalTokens}`,\n `input=${stats.inputTokens}`,\n `output=${stats.outputTokens}`,\n `cached=${stats.cachedTokens}`,\n `billed=${billedTokens}`,\n ];\n if (stats.cacheCreationTokens > 0) {\n parts.push(`cache_creation=${stats.cacheCreationTokens}`);\n }\n const avg = updateRollingAverage(durationMs);\n const ratio = avg > 0 ? durationMs / avg : 1;\n const color = ratio < 0.8 ? '\\x1b[32m' : ratio < 1.5 ? '\\x1b[33m' : '\\x1b[31m';\n const reset = '\\x1b[0m';\n const logMsg = `[${fmtTime(new Date())}] -> 200 (${color}${fmtDuration(durationMs)}${reset} avg=${fmtDuration(Math.round(avg))}) [${parts.join(', ')}]`;\n requestInfo.resultLog =\n stats.cachedTokens < 1024 && billedTokens > 0 ? `⚠️ NO CACHE -- ${logMsg}` : logMsg;\n\n if (options.onCacheStats) {\n options.onCacheStats({\n ...stats,\n method: requestInfo.method || undefined,\n url: requestInfo.url || undefined,\n durationMs: durationMs || undefined,\n });\n }\n },\n });\n\n const server = http.createServer(async (req, res) => {\n const start = Date.now();\n requestInfo.method = req.method ?? 'POST';\n requestInfo.url = req.url ?? '/v1/responses';\n requestInfo.startTime = start;\n\n const abortController = new AbortController();\n const timeoutMs = options.timeoutMs;\n let timeoutTimer: ReturnType<typeof setTimeout> | undefined;\n if (timeoutMs && timeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n logger?.warn(`[timeout] request exceeded ${timeoutMs}ms, aborting`);\n abortController.abort();\n res.destroy();\n req.destroy();\n }, timeoutMs);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await handleRequest(req, res, {\n apiFetch,\n cors,\n logger,\n method: req.method ?? 'POST',\n url: req.url ?? '/',\n upstreamCapture,\n requestInfo,\n requestTracker,\n signal: abortController.signal,\n });\n } catch (err) {\n logger?.error('[proxy-error]', err);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: 'Internal server error' } }));\n }\n /* c8 ignore start */\n } catch {\n // ignore\n } /* c8 ignore stop */\n } finally {\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n }\n }\n });\n\n return new Promise((resolve, reject) => {\n server.listen(port, host, () => {\n const actualPort = (() => {\n // eslint-disable-next-line no-restricted-syntax -- net.Server.address() returns string | AddressInfo | null\n const addr = server.address() as { port: number } | null;\n return addr.port;\n })();\n const url = `http://${host}:${actualPort}`;\n logger?.log(`Proxy listening on ${url}`);\n logger?.log(`Upstream format: ${options.upstreamFormat}`);\n logger?.log(`Upstream URL: ${options.baseUrl}`);\n resolve({\n host,\n port: actualPort,\n url,\n server,\n close: () =>\n new Promise((res) => {\n server.close((err) => {\n /* c8 ignore start */\n if (err) {\n logger?.warn('Error closing server:', err);\n }\n /* c8 ignore stop */\n res();\n });\n }),\n });\n });\n server.once('error', reject);\n });\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n opts: {\n apiFetch: typeof fetch;\n cors: boolean;\n logger: Pick<Console, 'log' | 'warn' | 'error'> | null;\n method: string;\n url: string;\n upstreamCapture: {\n request?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n response?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n };\n requestInfo: { resultLog: string };\n requestTracker: { add: (method: string, url: string) => string; remove: (id: string) => void };\n signal?: AbortSignal;\n },\n): Promise<void> {\n if (opts.cors) {\n setCorsHeaders(res);\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const method = req.method ?? 'GET';\n const urlPath = req.url ?? '/';\n const headers = flattenIncomingHeaders(req.headers);\n\n let body: Buffer | undefined;\n if (method !== 'GET' && method !== 'HEAD') {\n body = await readIncomingBody(req);\n }\n\n if (!/^\\/v1\\/responses\\/?(?:\\?|$)/.test(urlPath)) {\n res.writeHead(404, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: { message: `Not found: ${method} ${urlPath}` } }));\n return;\n }\n\n const requestBodyText = body ? body.toString('utf8') : undefined;\n\n const requestStart = Date.now();\n const requestId = opts.requestTracker.add(method, urlPath);\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const response = await opts.apiFetch(`http://local${urlPath}`, {\n method,\n headers,\n body: body ? new Uint8Array(body) : undefined,\n signal: opts.signal,\n });\n\n // Consume response body so onCacheStats fires (for streaming responses)\n const responseBodyText = response.body ? await response.clone().text() : '';\n\n // Remove from active requests and write final result\n opts.requestTracker.remove(requestId);\n /* c8 ignore start */\n if (opts.logger) {\n if (response.status >= 400) {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n } else if (opts.requestInfo.resultLog) {\n process.stdout.write(`\\r\\x1b[K${opts.requestInfo.resultLog}\\n`);\n } else {\n process.stdout.write(\n `\\r\\x1b[K<-- ${response.status} (${fmtDuration(Date.now() - requestStart)})\\n`,\n );\n }\n }\n /* c8 ignore stop */\n if (response.status >= 400) {\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const filePath = saveErrorDump({\n method: opts.method,\n url: opts.url,\n clientRequest: {\n headers,\n body: tryParseJson(requestBodyText ?? ''),\n },\n upstreamRequest: opts.upstreamCapture.request,\n upstreamResponse: opts.upstreamCapture.response,\n proxyResponse: {\n status: response.status,\n headers: headersToObject(response.headers),\n body: tryParseJson(responseBodyText),\n },\n });\n opts.logger?.error(`[proxy-failure] full exchange saved to ${filePath}`);\n } catch (dumpErr) {\n opts.logger?.error('[proxy-failure] failed to persist error dump', dumpErr);\n }\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n if (opts.cors) {\n Object.assign(outHeaders, corsHeaders());\n }\n\n res.writeHead(response.status, outHeaders);\n\n /* c8 ignore next 3 */\n if (!response.body) {\n res.end();\n return;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- fetch response.body is not typed as node stream\n const typedBody = response.body! as unknown as import('stream/web').ReadableStream<Uint8Array>;\n const nodeStream = Readable.fromWeb(typedBody);\n nodeStream.pipe(res);\n await new Promise<void>((resolve, reject) => {\n nodeStream.once('end', resolve);\n nodeStream.once('error', reject);\n res.once('close', resolve);\n });\n } catch (err) {\n opts.requestTracker.remove(requestId);\n throw err;\n }\n}\n\nfunction readIncomingBody(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk) => {\n const buf: Buffer = chunk;\n chunks.push(buf);\n });\n req.on('end', () => resolve(Buffer.concat(chunks)));\n req.on('error', reject);\n });\n}\n\nexport function flattenIncomingHeaders(\n headers: IncomingMessage['headers'],\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value == null) {\n continue;\n }\n out[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : String(value);\n }\n return out;\n}\n\nexport function headersToObject(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nfunction setCorsHeaders(res: ServerResponse): void {\n const headers = corsHeaders();\n for (const [key, value] of Object.entries(headers)) {\n res.setHeader(key, value);\n }\n}\n\nexport function corsHeaders(): Record<string, string> {\n return {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET,POST,OPTIONS',\n 'access-control-allow-headers':\n 'authorization,content-type,x-api-key,anthropic-version,anthropic-beta,anthropic-dangerous-direct-browser-access',\n 'access-control-expose-headers': 'content-type',\n };\n}\n\nexport function tryParseJson(str: string | undefined | null): unknown {\n if (!str) {\n return str ?? null;\n }\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n\nexport function headersInitToObject(headersInit: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!headersInit) {\n return out;\n }\n if (typeof Headers !== 'undefined' && headersInit instanceof Headers) {\n headersInit.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n if (Array.isArray(headersInit)) {\n for (const [key, value] of headersInit) {\n out[String(key).toLowerCase()] = String(value);\n }\n return out;\n }\n for (const [key, value] of Object.entries(headersInit)) {\n out[key.toLowerCase()] = String(value);\n }\n return out;\n}\n\nexport function saveErrorDump(dump: {\n method: string;\n url: string;\n clientRequest: { headers: Record<string, string>; body: unknown };\n upstreamRequest?: { url: string; method: string; headers: Record<string, string>; body: unknown };\n upstreamResponse?: {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n };\n proxyResponse: { status: number; headers: Record<string, string>; body: unknown };\n}): string {\n const dir = resolve(process.cwd(), 'logs');\n mkdirSync(dir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n const status = dump.upstreamResponse?.status ?? dump.proxyResponse.status;\n const filename = `proxy-error-${ts}-${status}.json`;\n const filePath = join(dir, filename);\n const payload = {\n timestamp: new Date().toISOString(),\n ...dump,\n };\n redactAuth(payload.clientRequest?.headers);\n redactAuth(payload.upstreamRequest?.headers);\n writeFileSync(filePath, JSON.stringify(payload, null, 2));\n return filePath;\n}\n\nexport function redactAuth(headers: Record<string, string> | undefined): void {\n if (!headers) {\n return;\n }\n for (const key of Object.keys(headers)) {\n const lowerKey = key.toLowerCase();\n if (\n lowerKey === 'authorization' ||\n lowerKey === 'x-api-key' ||\n lowerKey === 'api-key' ||\n lowerKey === 'cookie'\n ) {\n headers[key] = '[REDACTED]';\n }\n }\n}\n","// ==============================================================================\n// Config Loader\n// ==============================================================================\n/**\n * Configuration file loader and validator.\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n\nconst CONFIG_FILE_NAMES = [\n 'codeproxy.config.json',\n 'codeproxy.config.js',\n 'codeproxy.config.mjs',\n 'codeproxy.config.ts',\n '.codeproxy.json',\n '.codeproxy.js',\n] as const;\n\n/**\n * Find and load a config file.\n */\nexport async function loadConfigFile(\n searchFrom: string = process.cwd(),\n): Promise<ConfigFile | null> {\n const configPath = findConfigPath(searchFrom);\n if (!configPath) {\n return null;\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n if (configPath.endsWith('.json')) {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } else if (configPath.endsWith('.js') || configPath.endsWith('.mjs')) {\n /* c8 ignore start */\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } else if (configPath.endsWith('.ts')) {\n const module = await import(`file://${configPath}`);\n const defaultExport: ConfigFile = module.default;\n return defaultExport;\n } /* c8 ignore stop */\n return null; /* c8 ignore next -- trailing fallback */\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n return null;\n }\n}\n\nfunction findConfigPath(searchFrom: string): string | null {\n let currentDir = searchFrom;\n const root = parseRoot(searchFrom);\n\n while (currentDir !== root && currentDir !== dirname(currentDir)) {\n for (const name of CONFIG_FILE_NAMES) {\n const candidate = resolve(currentDir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n currentDir = dirname(currentDir);\n }\n\n return null;\n}\n\nfunction parseRoot(path: string): string {\n const parsed = resolve(path);\n const root = parsed.split(/[\\\\/]/)[0];\n return resolve(root);\n}\n\n/**\n * Validate the config file structure.\n */\nexport function validateConfig(config: unknown): { valid: boolean; error?: string } {\n if (typeof config !== 'object' || config === null) {\n return { valid: false, error: 'Config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = config as Record<string, unknown>;\n\n if (typeof cfg.version !== 'string') {\n return { valid: false, error: 'Config must have a version string' };\n }\n\n if (typeof cfg.currentUpstream !== 'string') {\n return { valid: false, error: 'Config must have a currentUpstream string' };\n }\n\n if (typeof cfg.upstreams !== 'object' || cfg.upstreams === null) {\n return { valid: false, error: 'Config must have an upstreams object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const upstreams: Record<string, unknown> = cfg.upstreams as Record<string, unknown>;\n\n if (!(cfg.currentUpstream in upstreams)) {\n return {\n valid: false,\n error: `currentUpstream \"${cfg.currentUpstream}\" not found in upstreams`,\n };\n }\n\n for (const [name, upstream] of Object.entries(upstreams)) {\n const result = validateUpstreamConfig(upstream);\n if (!result.valid) {\n return {\n valid: false,\n error: `Upstream \"${name}\" is invalid: ${result.error}`,\n };\n }\n }\n\n return { valid: true };\n}\n\nexport function validateUpstreamConfig(upstream: unknown): {\n valid: boolean;\n error?: string;\n} {\n if (typeof upstream !== 'object' || upstream === null) {\n return { valid: false, error: 'Upstream config must be an object' };\n }\n\n // eslint-disable-next-line no-restricted-syntax -- safe cast from object to Record\n const cfg: Record<string, unknown> = upstream as Record<string, unknown>;\n\n if (cfg.format !== undefined) {\n if (typeof cfg.format !== 'string') {\n return { valid: false, error: 'format must be a string if provided' };\n }\n const validFormats = ['anthropic', 'openai-chat'];\n if (!validFormats.includes(cfg.format)) {\n return {\n valid: false,\n error: `Invalid format: ${cfg.format}. Must be one of: ${validFormats.join(', ')}`,\n };\n }\n }\n\n if (typeof cfg.baseUrl !== 'string') {\n return { valid: false, error: 'baseUrl is required and must be a string' };\n }\n\n if (cfg.apiVersion !== undefined && typeof cfg.apiVersion !== 'string') {\n return { valid: false, error: 'apiVersion must be a string if provided' };\n }\n\n if (cfg.apiKey !== undefined && typeof cfg.apiKey !== 'string') {\n return { valid: false, error: 'apiKey must be a string if provided' };\n }\n\n if (cfg.model !== undefined && typeof cfg.model !== 'string') {\n return { valid: false, error: 'model must be a string if provided' };\n }\n\n if (cfg.dropImages !== undefined && typeof cfg.dropImages !== 'boolean') {\n return { valid: false, error: 'dropImages must be a boolean if provided' };\n }\n\n if (cfg.fallback !== undefined && typeof cfg.fallback !== 'string') {\n return { valid: false, error: 'fallback must be a string if provided' };\n }\n\n if (cfg.headers !== undefined && (typeof cfg.headers !== 'object' || cfg.headers === null)) {\n return { valid: false, error: 'headers must be an object if provided' };\n }\n\n if (cfg.reasoningEffort !== undefined && typeof cfg.reasoningEffort !== 'string') {\n return { valid: false, error: 'reasoningEffort must be a string if provided' };\n }\n\n // thinking is optional and can be any type; no validation needed\n\n return { valid: true };\n}\n\n/**\n * Get the current upstream config from a validated config file.\n */\nexport function getCurrentUpstreamConfig(config: ConfigFile): UpstreamConfig | null {\n const upstream = config.upstreams[config.currentUpstream];\n if (!upstream) {\n return null;\n }\n return upstream;\n}\n\n// Re-export types\nexport type { ConfigFile, UpstreamConfig } from '../types/config.js';\n","// ==============================================================================\n// Server Startup\n// ==============================================================================\n\n/**\n * `codeproxy` CLI.\n *\n * Usage:\n * npx codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n * npx codeproxy --config config.json\n */\n\nimport { readFileSync, existsSync } from 'node:fs';\nimport { startProxy, type StartProxyOptions } from './proxy.js';\nimport type { UpstreamFormat } from '@codeproxy/core';\nimport { validateConfig, getCurrentUpstreamConfig, type ConfigFile } from '../utils/config.js';\n\ninterface CliArgs {\n upstreamFormat?: UpstreamFormat | string;\n config?: string;\n host?: string;\n port?: number;\n baseUrl?: string;\n apiVersion?: string;\n apikey?: string;\n model?: string;\n cors?: boolean;\n dropImages?: boolean;\n help?: boolean;\n}\n\nexport function parseArgs(argv: string[]): CliArgs {\n const out: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n const take = () => argv[++i];\n switch (arg) {\n case '-h':\n case '--help':\n out.help = true;\n break;\n case '-p':\n case '--port':\n out.port = Number(take());\n break;\n case '--host':\n out.host = take();\n break;\n case '--upstream-format':\n out.upstreamFormat = take();\n break;\n case '--base-url':\n out.baseUrl = take();\n break;\n case '--config':\n out.config = take();\n break;\n case '--api-version':\n out.apiVersion = take();\n break;\n case '--apikey':\n out.apikey = take();\n break;\n case '--model':\n out.model = take();\n break;\n case '--drop-images':\n out.dropImages = true;\n break;\n case '--no-cors':\n out.cors = false;\n break;\n default:\n if (arg.startsWith('--upstream-format=')) {\n out.upstreamFormat = arg.slice('--upstream-format='.length);\n } else if (arg.startsWith('--port=')) {\n out.port = Number(arg.slice('--port='.length));\n } else if (arg.startsWith('--host=')) {\n out.host = arg.slice('--host='.length);\n } else if (arg.startsWith('--base-url=')) {\n out.baseUrl = arg.slice('--base-url='.length);\n } else if (arg.startsWith('--api-version=')) {\n out.apiVersion = arg.slice('--api-version='.length);\n } else if (arg.startsWith('--apikey=')) {\n out.apikey = arg.slice('--apikey='.length);\n } else if (arg.startsWith('--model=')) {\n out.model = arg.slice('--model='.length);\n } else if (arg.startsWith('--config=')) {\n out.config = arg.slice('--config='.length);\n } else {\n console.error(`Unknown argument: ${arg}`);\n out.help = true;\n }\n }\n }\n return out;\n}\n\nexport function printHelp(): void {\n console.log(`codeproxy - local Responses API proxy\n\nUsage:\n codeproxy --base-url <url> [options]\n codeproxy --config <file> [options]\n\nOptions:\n --base-url <url> Upstream endpoint URL (required when not using --config)\n --upstream-format <fmt> Upstream API format: anthropic | openai-chat\n (optional; inferred from --base-url when omitted:\n */messages or *anthropic* → anthropic,\n */chat/completions → openai-chat)\n --config <file> Use a config file instead of CLI flags\n --host <host> Bind host (default: 127.0.0.1)\n -p, --port <port> Bind port (default: 8787; 0 = random)\n --api-version <ver> Override anthropic-version header (anthropic only)\n --apikey <key> Override upstream Authorization: Bearer <key>\n --model <name> Override the model field in incoming requests\n --no-cors Disable CORS headers\n -h, --help Show help\n\nConfig File Mode:\n When using --config, upstream settings are loaded from the config file.\n Command-line options can override config values.\n\n Config file format (JSON):\n {\n \"version\": \"1.0\",\n \"currentUpstream\": \"my-claude\",\n \"upstreams\": {\n \"my-claude\": {\n \"baseUrl\": \"https://api.anthropic.com/v1/messages\",\n \"apiKey\": \"your-api-key\",\n \"model\": \"claude-sonnet-4-5\"\n },\n \"my-openai\": {\n \"baseUrl\": \"https://api.openai.com/v1/chat/completions\",\n \"apiKey\": \"your-openai-key\"\n }\n }\n }\n\n \"format\" is optional; inferred from baseUrl when omitted.\n\nAuth is caller-driven: send Authorization: Bearer <key> (or the upstream's\nnative header) when calling the proxy. Nothing is stored server-side.\n\nExamples:\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages\n codeproxy --upstream-format openai-chat --base-url https://api.openai.com/v1/chat/completions\n codeproxy --config my-config.json\n codeproxy --upstream-format anthropic --base-url https://api.anthropic.com/v1/messages --apikey <key>\n`);\n}\n\nexport async function loadConfigFile(configPath: string): Promise<ConfigFile> {\n if (!existsSync(configPath)) {\n console.error(`Config file not found: ${configPath}`);\n process.exit(1);\n }\n\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed: ConfigFile = JSON.parse(content);\n return parsed;\n } catch (error) {\n console.error(`Failed to load config from ${configPath}:`, error);\n process.exit(1);\n }\n}\n\nexport async function loadConfigAndApplyOverrides(\n configPath: string,\n overrides: CliArgs,\n): Promise<StartProxyOptions> {\n const config = await loadConfigFile(configPath);\n\n const validation = validateConfig(config);\n if (!validation.valid) {\n console.error(`Invalid config file: ${validation.error}`);\n process.exit(1);\n }\n\n const upstreamConfig = getCurrentUpstreamConfig(config);\n /* c8 ignore start */ if (!upstreamConfig) {\n console.error(`Current upstream \"${config.currentUpstream}\" not found in config`);\n process.exit(1);\n } /* c8 ignore stop */\n\n console.log(`Loaded config from: ${configPath}`);\n console.log(\n `Current upstream: ${config.currentUpstream}${upstreamConfig.format ? ` (${upstreamConfig.format})` : ''}`,\n );\n console.log(`Model: ${upstreamConfig.model || '(not set)'}`);\n const mergedEffort = upstreamConfig.reasoningEffort ?? config.reasoningEffort;\n if (mergedEffort) {\n console.log(`Reasoning effort: ${mergedEffort}`);\n }\n const mergedHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(mergedHeaders, upstreamConfig.headers);\n }\n if (mergedHeaders.authorization) {\n mergedHeaders.authorization = '\"[REDACTED]\"';\n }\n if (Object.keys(mergedHeaders).length > 0) {\n console.log(`Headers: ${JSON.stringify(mergedHeaders)}`);\n }\n // ==============================================================================\n // Proxy Launch\n // ==============================================================================\n\n const options: StartProxyOptions = {\n upstreamFormat: upstreamConfig.format,\n baseUrl: overrides.baseUrl || upstreamConfig.baseUrl,\n apiVersion: overrides.apiVersion || upstreamConfig.apiVersion,\n model: overrides.model || upstreamConfig.model,\n host: overrides.host || upstreamConfig.host,\n port:\n overrides.port !== undefined\n ? overrides.port\n : // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n (config as unknown as Record<string, unknown>).port\n ? // eslint-disable-next-line no-restricted-syntax -- access dynamic config key\n Number((config as unknown as Record<string, unknown>).port)\n : upstreamConfig.port\n ? Number(upstreamConfig.port)\n : undefined,\n timeoutMs: upstreamConfig.timeoutMs ?? config.timeoutMs,\n dropImages: upstreamConfig.dropImages,\n cors: overrides.cors,\n reasoning_effort: upstreamConfig.reasoningEffort ?? config.reasoningEffort,\n thinking: upstreamConfig.thinking ?? config.thinking,\n };\n\n const defaultHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (upstreamConfig.headers) {\n Object.assign(defaultHeaders, upstreamConfig.headers);\n }\n if (upstreamConfig.apiKey) {\n defaultHeaders.authorization = `Bearer ${upstreamConfig.apiKey}`;\n }\n if (overrides.apikey) {\n defaultHeaders.authorization = `Bearer ${overrides.apikey}`;\n }\n\n if (Object.keys(defaultHeaders).length > 0) {\n options.defaultHeaders = defaultHeaders;\n }\n\n // Resolve fallback upstream if configured\n if (upstreamConfig.fallback) {\n const fbConfig = config.upstreams[upstreamConfig.fallback];\n if (fbConfig) {\n const fbHeaders: Record<string, string> = { ...(config.headers ?? {}) };\n if (fbConfig.headers) {\n Object.assign(fbHeaders, fbConfig.headers);\n }\n if (fbConfig.apiKey) {\n fbHeaders.authorization = `Bearer ${fbConfig.apiKey}`;\n }\n const fbFormat: UpstreamFormat | undefined = fbConfig.format;\n options.fallbackUpstream = {\n baseUrl: fbConfig.baseUrl,\n upstreamFormat: fbFormat,\n model: fbConfig.model ?? options.model,\n defaultHeaders: Object.keys(fbHeaders).length > 0 ? fbHeaders : undefined,\n apiVersion: fbConfig.apiVersion ?? options.apiVersion,\n reasoning_effort: fbConfig.reasoningEffort ?? options.reasoning_effort,\n thinking: fbConfig.thinking ?? options.thinking,\n };\n console.log(\n `Fallback upstream: ${upstreamConfig.fallback}${fbConfig.model ? ` (${fbConfig.model})` : ''}`,\n );\n } else {\n console.warn(`Warning: fallback upstream \"${upstreamConfig.fallback}\" not found in config`);\n }\n }\n\n return options;\n}\n\n/* c8 ignore next -- main is entry point */\nexport async function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n\n if (args.help) {\n printHelp();\n process.exit(0);\n }\n\n let options: StartProxyOptions;\n\n if (args.config) {\n options = await loadConfigAndApplyOverrides(args.config, args);\n } else if (args.baseUrl) {\n // eslint-disable-next-line no-restricted-syntax -- parsed string may not match union type\n const upstreamFormat = args.upstreamFormat as UpstreamFormat | undefined;\n options = {\n upstreamFormat,\n baseUrl: args.baseUrl,\n host: args.host,\n port: args.port,\n apiVersion: args.apiVersion,\n model: args.model,\n defaultHeaders: args.apikey ? { authorization: `Bearer ${args.apikey}` } : undefined,\n dropImages: args.dropImages,\n cors: args.cors,\n };\n } else {\n console.error('Error: Either --config <file> or --base-url <url> is required');\n console.error('');\n printHelp();\n process.exit(1);\n }\n\n const proxy = await startProxy(options);\n /* c8 ignore start */\n const shutdown = async (signal: string) => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n // eslint-disable-next-line no-restricted-syntax -- try/catch needed for server-side HTTP error handling\n try {\n await proxy.close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', () => void shutdown('SIGINT'));\n process.on('SIGTERM', () => void shutdown('SIGTERM'));\n /* c8 ignore stop */\n}\n\n/* c8 ignore start */\nif (process.argv[1]?.endsWith('cli.js') || process.argv[1]?.endsWith('cli.ts') || process.argv[1]?.endsWith('codeproxy')) {\n void main();\n}\n/* c8 ignore stop */\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeproxy/cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Local proxy server that converts any Chat Completions / Anthropic Messages API into OpenAI Responses API so Codex and Claude Code can use any LLM.",
5
5
  "keywords": [
6
6
  "openai",