@agimon-ai/model-proxy-mcp 0.5.1 → 0.5.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.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":["WORKSPACE_MARKERS","SIGTERM_SIGNAL: NodeJS.Signals","SIGKILL_SIGNAL: NodeJS.Signals","PORT_REGISTRY_SERVICE_TYPE","resolveWorkspaceRoot","fs","health","DEFAULT_SCOPE","TEXT_ENCODING: BufferEncoding","MODEL_PROXY_SCOPE_ENV","code: string","fs","processLease: ProcessLease | undefined","DEFAULT_SCOPE"],"sources":["../src/services/HttpServerHealthCheck.ts","../src/services/HttpServerManager.ts","../src/commands/claude.ts","../src/commands/http-serve.ts","../src/commands/mcp-serve.ts","../src/commands/start.ts","../src/commands/status.ts","../src/commands/stop.ts","../src/cli.ts"],"sourcesContent":["export interface HealthCheckResult {\n healthy: boolean;\n serviceName?: string;\n error?: string;\n}\n\nexport class HttpServerHealthCheck {\n async check(port: number): Promise<HealthCheckResult> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`);\n if (!response.ok) {\n return { healthy: false, error: `Health check failed with status ${response.status}` };\n }\n\n const payload = (await response.json()) as { service?: string };\n return {\n healthy: true,\n serviceName: payload.service,\n };\n } catch (error) {\n return {\n healthy: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","import { execFile, spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\nimport { PortRegistryService } from '@agimon-ai/foundation-port-registry';\nimport { DEFAULT_HTTP_PORT, DEFAULT_SERVICE_NAME, MODEL_PROXY_PORT_RANGE } from '../constants/defaults.js';\nimport type { GatewayStatus } from '../types/index.js';\nimport { HttpServerHealthCheck } from './HttpServerHealthCheck.js';\n\nconst WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'nx.json', '.git'];\nconst SHELL_BINARY = 'sh';\nconst LSOF_COMMAND_PREFIX = 'lsof -n -P -sTCP:LISTEN';\nconst HEALTH_CHECK_STABILIZE_MS = 5000;\nconst HEALTH_CHECK_POLL_INTERVAL_MS = 250;\nconst PROCESS_SHUTDOWN_WAIT_MS = 1000;\nconst SIGTERM_SIGNAL: NodeJS.Signals = 'SIGTERM';\nconst SIGKILL_SIGNAL: NodeJS.Signals = 'SIGKILL';\nconst PORT_REGISTRY_SERVICE_TYPE = 'service' as const;\nconst execFileAsync = promisify(execFile);\n\nfunction resolveWorkspaceRoot(startPath = process.cwd()): string {\n let currentDir = path.resolve(startPath);\n\n while (true) {\n for (const marker of WORKSPACE_MARKERS) {\n if (existsSync(path.join(currentDir, marker))) {\n return currentDir;\n }\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n return process.cwd();\n }\n currentDir = parentDir;\n }\n}\n\ninterface PortListener {\n port: number;\n pid: number;\n}\n\ntype CliRuntime = 'node' | 'bun';\n\nexport class HttpServerManager {\n private readonly repositoryPath = resolveWorkspaceRoot(process.cwd());\n private readonly serviceName = DEFAULT_SERVICE_NAME;\n private readonly portRegistry: PortRegistryService;\n\n constructor(private readonly healthCheck = new HttpServerHealthCheck()) {\n this.portRegistry = new PortRegistryService(process.env.PORT_REGISTRY_PATH);\n }\n\n private createEmptyStatus(overrides: Partial<GatewayStatus> = {}): GatewayStatus {\n return {\n running: false,\n scope: 'default',\n activeProfileId: null,\n auth: { configured: false, authFilePath: '' },\n profiles: [],\n slotModels: {},\n ...overrides,\n };\n }\n\n private async getRegistration(): Promise<{ port: number; pid?: number } | null> {\n const result = await this.portRegistry.getPort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n });\n if (!result.success || !result.record) {\n return null;\n }\n return { port: result.record.port, pid: result.record.pid };\n }\n\n private async releaseService(pid?: number): Promise<void> {\n await this.portRegistry.releasePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid,\n });\n }\n\n private async listListeningProcesses(port: number): Promise<PortListener[]> {\n try {\n const { stdout } = await execFileAsync(SHELL_BINARY, ['-lc', `${LSOF_COMMAND_PREFIX} -iTCP:${port} || true`], {\n encoding: 'utf8',\n });\n return stdout\n .split('\\n')\n .slice(1)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => line.split(/\\s+/))\n .map((parts) => ({\n pid: Number.parseInt(parts[1] || '', 10),\n port,\n }))\n .filter((listener) => Number.isInteger(listener.pid) && listener.pid > 0);\n } catch {\n return [];\n }\n }\n\n private async findHealthyServicePort(): Promise<number | null> {\n const registration = await this.getRegistration();\n if (registration) {\n const health = await this.healthCheck.check(registration.port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return registration.port;\n }\n }\n return null;\n }\n\n private async clearPortListeners(port: number, preservePid?: number): Promise<void> {\n const listeners = await this.listListeningProcesses(port);\n for (const listener of listeners) {\n if (preservePid && listener.pid === preservePid) {\n continue;\n }\n await this.killProcess(listener.pid);\n }\n }\n\n private async registerService(port: number, pid: number): Promise<void> {\n await this.portRegistry.reservePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n preferredPort: port,\n portRange: { min: port, max: port },\n pid,\n host: '127.0.0.1',\n force: true,\n });\n }\n\n private async findAvailablePort(preferredPort: number): Promise<number> {\n const result = await this.portRegistry.findAvailablePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n host: '127.0.0.1',\n preferredPort,\n portRange: MODEL_PROXY_PORT_RANGE,\n });\n if (!result.success || result.port === undefined) {\n throw new Error(`No available port found from ${preferredPort}`);\n }\n return result.port;\n }\n\n private async fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n private async resolveCliPath(): Promise<{ cliPath: string; runtime: CliRuntime }> {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n\n // Bundled dist output: cli.mjs lives in the same directory as this file\n const sameDirCliPath = path.resolve(currentDir, 'cli.mjs');\n if (await this.fileExists(sameDirCliPath)) {\n return { cliPath: sameDirCliPath, runtime: 'node' };\n }\n\n // Unbundled dist output: this file is in dist/services/, cli.mjs is in dist/\n const parentDirCliPath = path.resolve(currentDir, '..', 'cli.mjs');\n if (await this.fileExists(parentDirCliPath)) {\n return { cliPath: parentDirCliPath, runtime: 'node' };\n }\n\n // Workspace fallbacks for monorepo development\n const repoDistCliPath = path.join(this.repositoryPath, 'packages', 'mcp', 'model-proxy-mcp', 'dist', 'cli.mjs');\n if (await this.fileExists(repoDistCliPath)) {\n return { cliPath: repoDistCliPath, runtime: 'node' };\n }\n\n // Dev mode: source cli.ts next to this file or one level up\n for (const relPath of [path.resolve(currentDir, 'cli.ts'), path.resolve(currentDir, '..', 'cli.ts')]) {\n if (await this.fileExists(relPath)) {\n return { cliPath: relPath, runtime: 'bun' };\n }\n }\n\n const repoSrcCliPath = path.join(this.repositoryPath, 'packages', 'mcp', 'model-proxy-mcp', 'src', 'cli.ts');\n if (await this.fileExists(repoSrcCliPath)) {\n return { cliPath: repoSrcCliPath, runtime: 'bun' };\n }\n\n throw new Error('Cannot find model-proxy-mcp CLI');\n }\n\n private async startHttpServer(port: number): Promise<number> {\n const { cliPath, runtime } = await this.resolveCliPath();\n\n const command = runtime === 'bun' ? (process.versions.bun ? process.execPath : 'bun') : 'node';\n const args =\n runtime === 'bun'\n ? ['run', cliPath, 'http-serve', '--port', String(port)]\n : [cliPath, 'http-serve', '--port', String(port)];\n\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: process.env.NODE_ENV || 'development',\n },\n });\n\n child.unref();\n if (!child.pid) {\n throw new Error('Failed to spawn HTTP server');\n }\n\n return child.pid;\n }\n\n private async killProcess(pid: number): Promise<void> {\n try {\n process.kill(pid, SIGTERM_SIGNAL);\n await new Promise((resolve) => setTimeout(resolve, PROCESS_SHUTDOWN_WAIT_MS));\n try {\n process.kill(pid, 0);\n process.kill(pid, SIGKILL_SIGNAL);\n } catch {\n return;\n }\n } catch {\n return;\n }\n }\n\n private async waitForHealthy(port: number): Promise<{ healthy: boolean; error?: string }> {\n const deadline = Date.now() + HEALTH_CHECK_STABILIZE_MS;\n let lastError = 'Server failed health check after startup';\n\n while (Date.now() < deadline) {\n const health = await this.healthCheck.check(port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return { healthy: true };\n }\n\n lastError = health.error || `Unexpected service on port ${port}`;\n await new Promise((resolve) => setTimeout(resolve, HEALTH_CHECK_POLL_INTERVAL_MS));\n }\n\n return { healthy: false, error: lastError };\n }\n\n async ensureRunning(port = DEFAULT_HTTP_PORT): Promise<GatewayStatus> {\n try {\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const healthyListeners = await this.listListeningProcesses(healthyPort);\n const healthyPid = healthyListeners[0]?.pid;\n await this.registerService(healthyPort, healthyPid ?? process.pid);\n return this.createEmptyStatus({ running: true, port: healthyPort, pid: healthyPid });\n }\n\n const existing = await this.getRegistration();\n if (existing) {\n const health = await this.healthCheck.check(existing.port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return this.createEmptyStatus({ running: true, port: existing.port, pid: existing.pid });\n }\n\n if (existing.pid) {\n await this.killProcess(existing.pid);\n }\n await this.clearPortListeners(existing.port, existing.pid);\n await this.releaseService(existing.pid);\n }\n\n await this.clearPortListeners(port);\n const availablePort = await this.findAvailablePort(port);\n const pid = await this.startHttpServer(availablePort);\n const health = await this.waitForHealthy(availablePort);\n if (!health.healthy) {\n await this.killProcess(pid);\n await this.clearPortListeners(availablePort, pid);\n await this.releaseService(pid);\n return this.createEmptyStatus({ error: health.error || 'Server failed health check after startup' });\n }\n\n await this.registerService(availablePort, pid);\n return this.createEmptyStatus({ running: true, port: availablePort, pid });\n } catch (error) {\n return this.createEmptyStatus({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n async stop(): Promise<boolean> {\n const registration = await this.getRegistration();\n let stopped = false;\n\n if (registration?.pid) {\n await this.killProcess(registration.pid);\n stopped = true;\n }\n if (registration) {\n await this.clearPortListeners(registration.port, registration.pid);\n await this.releaseService(registration.pid);\n }\n\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const listeners = await this.listListeningProcesses(healthyPort);\n for (const listener of listeners) {\n await this.killProcess(listener.pid);\n stopped = true;\n }\n await this.releaseService();\n }\n\n return stopped;\n }\n\n async getStatus(): Promise<GatewayStatus> {\n const registration = await this.getRegistration();\n if (registration) {\n const health = await this.healthCheck.check(registration.port);\n if (health.healthy) {\n return this.createEmptyStatus({\n running: true,\n port: registration.port,\n pid: registration.pid,\n });\n }\n }\n\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const listeners = await this.listListeningProcesses(healthyPort);\n const pid = listeners[0]?.pid;\n if (pid) {\n await this.registerService(healthyPort, pid);\n }\n return this.createEmptyStatus({\n running: true,\n port: healthyPort,\n pid,\n });\n }\n\n return this.createEmptyStatus({\n error: registration ? 'Registered server is unhealthy' : 'No HTTP server registered',\n });\n }\n}\n","import { spawn } from 'node:child_process';\nimport { randomBytes, randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { ProfileStore } from '../services/ProfileStore.js';\n\nconst CLAUDE_BINARY = 'claude';\nconst DEFAULT_SCOPE = 'default';\nconst SESSIONS_DIRECTORY_NAME = '.claude-sessions';\nconst RANDOM_SCOPE_PREFIX = 'scope';\nconst RANDOM_SCOPE_BYTES = 3;\nconst TEXT_ENCODING: BufferEncoding = 'utf8';\nconst STDIO_INHERIT = 'inherit';\nconst DECIMAL_RADIX = 10;\nconst LOG_PREFIX = '[model-proxy-mcp]';\nconst RECOVERY_MESSAGE = `Recovery: verify HOME, proxy port, and that \\`${CLAUDE_BINARY}\\` is on PATH.`;\nconst ARG_RESUME = '--resume';\nconst ARG_SESSION_ID = '--session-id';\nconst ARG_SKIP_PERMISSIONS = '--dangerously-skip-permissions';\nconst MODEL_ALIAS_OPUS = 'ccproxy-opus';\nconst MODEL_ALIAS_SONNET = 'ccproxy-sonnet';\nconst MODEL_ALIAS_HAIKU = 'ccproxy-haiku';\nconst MODEL_ALIAS_SUBAGENT = 'ccproxy-subagent';\nconst DEFAULT_SCOPE_SEED_FILE = 'model-proxy-mcp.yaml';\nconst MODEL_PROXY_SCOPE_ENV = 'MODEL_PROXY_MCP_SCOPE';\nconst MODEL_PROXY_SLOT_ENV = 'MODEL_PROXY_MCP_SLOT';\nconst DEFAULT_MODEL_PROXY_SLOT = 'default';\n\nclass ClaudeCommandError extends Error {\n constructor(\n message: string,\n readonly code: string,\n options?: {\n cause?: unknown;\n },\n ) {\n super(message, options);\n this.name = 'ClaudeCommandError';\n }\n}\n\nclass ClaudeCommandConfigError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_CONFIG_ERROR', options);\n this.name = 'ClaudeCommandConfigError';\n }\n}\n\nclass ClaudeCommandValidationError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_VALIDATION_ERROR', options);\n this.name = 'ClaudeCommandValidationError';\n }\n}\n\nclass ClaudeCommandLaunchError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_LAUNCH_ERROR', options);\n this.name = 'ClaudeCommandLaunchError';\n }\n}\n\nexport function sanitizeScope(scope: string): string {\n const sanitized = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return sanitized || DEFAULT_SCOPE;\n}\n\nexport function generateScopeName(): string {\n return `${RANDOM_SCOPE_PREFIX}-${randomBytes(RANDOM_SCOPE_BYTES).toString('hex')}`;\n}\n\nexport function buildClaudeEnvironment(\n port: number,\n scope: string,\n baseEnvironment: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...baseEnvironment,\n ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}/scopes/${scope}`,\n ANTHROPIC_DEFAULT_OPUS_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_OPUS_MODEL || MODEL_ALIAS_OPUS,\n ANTHROPIC_DEFAULT_SONNET_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_SONNET_MODEL || MODEL_ALIAS_SONNET,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_HAIKU_MODEL || MODEL_ALIAS_HAIKU,\n CLAUDE_CODE_SUBAGENT_MODEL: baseEnvironment.CLAUDE_CODE_SUBAGENT_MODEL || MODEL_ALIAS_SUBAGENT,\n MODEL_PROXY_MCP_SCOPE: baseEnvironment[MODEL_PROXY_SCOPE_ENV] || scope,\n MODEL_PROXY_MCP_SLOT: baseEnvironment[MODEL_PROXY_SLOT_ENV] || DEFAULT_MODEL_PROXY_SLOT,\n };\n}\n\nexport async function resolveScopeSeedConfigPath(\n configFile: string | undefined,\n workingDirectory = process.cwd(),\n): Promise<string | undefined> {\n const candidate = configFile\n ? path.resolve(workingDirectory, configFile)\n : path.join(workingDirectory, DEFAULT_SCOPE_SEED_FILE);\n\n try {\n const stats = await fs.stat(candidate);\n if (!stats.isFile()) {\n if (configFile) {\n throw new ClaudeCommandConfigError(`Scope seed config path is not a file: ${candidate}`);\n }\n return undefined;\n }\n return candidate;\n } catch (error) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code === 'ENOENT') {\n if (configFile) {\n throw new ClaudeCommandConfigError(`Scope seed config file not found: ${candidate}`, { cause: error });\n }\n return undefined;\n }\n if (error instanceof ClaudeCommandConfigError) {\n throw error;\n }\n throw new ClaudeCommandConfigError(`Failed to read scope seed config file: ${candidate}`, { cause: error });\n }\n}\n\nfunction getSessionsDirectory(): string {\n const homeDirectory = process.env.HOME || process.env.USERPROFILE;\n if (!homeDirectory) {\n throw new ClaudeCommandConfigError('HOME or USERPROFILE is not set');\n }\n\n return path.join(homeDirectory, SESSIONS_DIRECTORY_NAME);\n}\n\nasync function ensureSessionsDirectory(): Promise<string> {\n const sessionsDirectory = getSessionsDirectory();\n await fs.mkdir(sessionsDirectory, { recursive: true });\n return sessionsDirectory;\n}\n\nasync function readSessionId(sessionFile: string): Promise<string | null> {\n try {\n const sessionId = (await fs.readFile(sessionFile, TEXT_ENCODING)).trim();\n return sessionId || null;\n } catch (error) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code === 'ENOENT') {\n return null;\n }\n throw new ClaudeCommandConfigError(`Failed to read Claude session file: ${sessionFile}`, { cause: error });\n }\n}\n\nasync function resolveSessionId(scope: string, clearSession: boolean): Promise<{ sessionId: string; resume: boolean }> {\n const sessionsDirectory = await ensureSessionsDirectory();\n const sessionFile = path.join(sessionsDirectory, scope);\n\n if (clearSession) {\n try {\n await fs.rm(sessionFile, { force: true });\n } catch (error) {\n throw new ClaudeCommandConfigError(`Failed to clear Claude session file: ${sessionFile}`, { cause: error });\n }\n }\n\n const existingSessionId = await readSessionId(sessionFile);\n if (existingSessionId) {\n return { sessionId: existingSessionId, resume: true };\n }\n\n const sessionId = randomUUID().toLowerCase();\n try {\n await fs.writeFile(sessionFile, `${sessionId}\\n`, TEXT_ENCODING);\n } catch (error) {\n throw new ClaudeCommandConfigError(`Failed to write Claude session file: ${sessionFile}`, { cause: error });\n }\n return { sessionId, resume: false };\n}\n\nasync function launchClaude(\n scope: string,\n port: number,\n clearSession: boolean,\n claudeArgs: string[],\n configFile?: string,\n): Promise<number> {\n const scopeSeedConfigPath = await resolveScopeSeedConfigPath(configFile);\n const profileStore = new ProfileStore();\n await profileStore.ensureConfig(scope, scopeSeedConfigPath);\n\n const serverManager = new HttpServerManager();\n const status = await serverManager.ensureRunning(port);\n\n if (!status.running || !status.port) {\n throw new ClaudeCommandLaunchError(status.error || 'Failed to start model proxy HTTP server');\n }\n\n const { sessionId, resume } = await resolveSessionId(scope, clearSession);\n const env = buildClaudeEnvironment(status.port, scope);\n const args = [\n ARG_SKIP_PERMISSIONS,\n ...(resume ? [ARG_RESUME, sessionId] : [ARG_SESSION_ID, sessionId]),\n ...claudeArgs,\n ];\n\n console.log(`${LOG_PREFIX} Scope: ${scope}`);\n console.log(`${LOG_PREFIX} Proxy: ${env.ANTHROPIC_BASE_URL}`);\n console.log(`${LOG_PREFIX} Session: ${sessionId}${resume ? ' (resume)' : ' (new)'}`);\n if (scopeSeedConfigPath) {\n console.log(`${LOG_PREFIX} Scope config seed: ${scopeSeedConfigPath}`);\n }\n\n return new Promise<number>((resolve, reject) => {\n const child = spawn(CLAUDE_BINARY, args, {\n stdio: STDIO_INHERIT,\n env,\n });\n\n child.on('error', (error) => {\n reject(\n new ClaudeCommandLaunchError(`Failed to launch ${CLAUDE_BINARY}`, {\n cause: error,\n }),\n );\n });\n\n child.on('exit', (code, signal) => {\n if (signal) {\n reject(new ClaudeCommandLaunchError(`${CLAUDE_BINARY} exited with signal ${signal}`));\n return;\n }\n resolve(code ?? 0);\n });\n });\n}\n\nexport const claudeCommand = new Command('claude')\n .description('Launch Claude Code through the model proxy')\n .option('-s, --scope <scope>', 'Proxy scope to use')\n .option('-p, --port <port>', 'Preferred HTTP port for the proxy', String(DEFAULT_HTTP_PORT))\n .option('-c, --config-file <path>', 'Seed a new scope from the specified scope config file')\n .option('--config <path>', 'Alias for --config-file')\n .option('--clear-session', 'Start with a fresh Claude session for the selected scope', false)\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .argument('[claudeArgs...]')\n .action(\n async (\n claudeArgs: string[],\n options: { scope?: string; port: string; clearSession: boolean; configFile?: string; config?: string },\n ) => {\n try {\n const resolvedScope = sanitizeScope(options.scope || generateScopeName());\n const port = Number.parseInt(options.port, DECIMAL_RADIX);\n if (!Number.isInteger(port) || port <= 0) {\n throw new ClaudeCommandValidationError(`Invalid port: ${options.port}`);\n }\n\n const exitCode = await launchClaude(\n resolvedScope,\n port,\n options.clearSession,\n claudeArgs,\n options.configFile ?? options.config,\n );\n process.exit(exitCode);\n } catch (error) {\n const commandError =\n error instanceof ClaudeCommandError\n ? error\n : new ClaudeCommandLaunchError('Failed to launch Claude', { cause: error });\n console.error(`${LOG_PREFIX} ${commandError.code}: ${commandError.message}`);\n console.error(`${LOG_PREFIX} ${RECOVERY_MESSAGE}`);\n if (commandError.cause) {\n console.error(`${LOG_PREFIX} Cause:`, commandError.cause);\n }\n process.exit(1);\n }\n },\n );\n","import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { PortRegistryService } from '@agimon-ai/foundation-port-registry';\nimport { type ProcessLease, createProcessLease } from '@agimon-ai/foundation-process-registry';\nimport { serve } from '@hono/node-server';\nimport { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT, DEFAULT_SERVICE_NAME, MODEL_PROXY_PORT_RANGE } from '../constants/defaults.js';\nimport { createHttpServer } from '../server/http.js';\nimport { GatewayService } from '../services/GatewayService.js';\n\nconst LOCAL_HOST = '127.0.0.1';\nconst WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'nx.json', '.git'];\nconst PORT_REGISTRY_SERVICE_TYPE = 'service' as const;\n\ntype HttpServeOptions = { port: string };\n\nfunction resolveWorkspaceRoot(startPath = process.cwd()): string {\n let current = path.resolve(startPath);\n while (true) {\n for (const marker of WORKSPACE_MARKERS) {\n if (existsSync(path.join(current, marker))) {\n return current;\n }\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return process.cwd();\n }\n current = parent;\n }\n}\n\nexport const httpServeCommand = new Command('http-serve')\n .description('Start the Claude-compatible HTTP model proxy server')\n .option('-p, --port <port>', 'Port to listen on', String(DEFAULT_HTTP_PORT))\n .action(async (options: HttpServeOptions) => {\n let processLease: ProcessLease | undefined;\n try {\n const requestedPort = Number.parseInt(options.port, 10);\n if (!Number.isInteger(requestedPort) || requestedPort <= 0) {\n throw new Error(`Invalid port: ${options.port}`);\n }\n\n const portRegistry = new PortRegistryService(process.env.PORT_REGISTRY_PATH);\n const repositoryPath = resolveWorkspaceRoot();\n const reserveResult = await portRegistry.reservePort({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n preferredPort: requestedPort,\n portRange: MODEL_PROXY_PORT_RANGE,\n pid: process.pid,\n host: LOCAL_HOST,\n force: true,\n });\n\n if (!reserveResult.success || !reserveResult.record) {\n throw new Error(reserveResult.error || `Failed to reserve port ${requestedPort}`);\n }\n\n const port = reserveResult.record.port;\n\n processLease = await createProcessLease({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid: process.pid,\n port,\n host: LOCAL_HOST,\n command: process.argv[1],\n args: process.argv.slice(2),\n });\n\n const gatewayService = new GatewayService();\n await gatewayService.ensureConfig();\n const app = createHttpServer(gatewayService);\n const server = serve({ fetch: app.fetch, port, hostname: LOCAL_HOST });\n\n console.log(`model-proxy-mcp listening on http://${LOCAL_HOST}:${port}`);\n console.log(`Claude base URL: http://${LOCAL_HOST}:${port}`);\n\n const shutdown = async (signal: string) => {\n console.log(`\\n${signal} received. Shutting down...`);\n server.close();\n await processLease?.release();\n await portRegistry.releasePort({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid: process.pid,\n });\n process.exit(0);\n };\n\n process.once('SIGINT', () => shutdown('SIGINT'));\n process.once('SIGTERM', () => shutdown('SIGTERM'));\n } catch (error) {\n await processLease?.release();\n console.error('Failed to start HTTP server:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { createServer } from '../server/index.js';\nimport { GatewayService } from '../services/GatewayService.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\nconst DEFAULT_SCOPE = 'default';\nconst MODEL_PROXY_SCOPE_ENV = 'MODEL_PROXY_MCP_SCOPE';\n\ntype McpServeOptions = { cleanup: boolean; port: string };\n\nexport const mcpServeCommand = new Command('mcp-serve')\n .description('Start MCP server with stdio transport')\n .option('--cleanup', 'Stop HTTP server on shutdown', false)\n .option('-p, --port <port>', 'Port for HTTP server', String(DEFAULT_HTTP_PORT))\n .action(async (options: McpServeOptions) => {\n try {\n const port = Number.parseInt(options.port, 10);\n if (!Number.isInteger(port) || port <= 0) {\n throw new Error(`Invalid port: ${options.port}`);\n }\n\n const gatewayService = new GatewayService();\n await gatewayService.ensureConfig(process.env[MODEL_PROXY_SCOPE_ENV] || DEFAULT_SCOPE);\n\n const manager = new HttpServerManager();\n const httpStatus = await manager.ensureRunning(port);\n if (!httpStatus.running) {\n console.error(`Warning: HTTP server failed to start: ${httpStatus.error}`);\n }\n\n const handler = new StdioTransportHandler(createServer(gatewayService));\n\n const shutdown = async (signal: string) => {\n console.error(`\\nReceived ${signal}, shutting down gracefully...`);\n await handler.stop();\n if (options.cleanup && httpStatus.running) {\n await manager.stop();\n }\n process.exit(0);\n };\n\n process.once(\n 'SIGINT',\n () =>\n void shutdown('SIGINT').catch((error) => {\n console.error('Failed to shut down after SIGINT:', error);\n process.exit(1);\n }),\n );\n process.once(\n 'SIGTERM',\n () =>\n void shutdown('SIGTERM').catch((error) => {\n console.error('Failed to shut down after SIGTERM:', error);\n process.exit(1);\n }),\n );\n\n await handler.start();\n } catch (error) {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { createServer } from '../server/index.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\nexport const startCommand = new Command('start')\n .description('Start HTTP and/or MCP server for the model proxy')\n .option('--mcp-only', 'Start only the MCP server', false)\n .option('--http-only', 'Start only the HTTP server', false)\n .option('-p, --port <port>', 'Port for HTTP server', String(DEFAULT_HTTP_PORT))\n .action(async (options) => {\n try {\n const httpServerManager = new HttpServerManager();\n const port = Number.parseInt(options.port, 10);\n const startHttp = !options.mcpOnly;\n const startMcp = !options.httpOnly;\n\n if (startHttp) {\n const status = await httpServerManager.ensureRunning(port);\n if (!status.running) {\n console.error(`HTTP server failed to start: ${status.error}`);\n process.exit(1);\n }\n console.log(`HTTP server running on http://127.0.0.1:${status.port}`);\n }\n\n if (startMcp) {\n const handler = new StdioTransportHandler(createServer());\n await handler.start();\n const shutdown = async (signal: string) => {\n console.error(`\\n${signal} received. Shutting down...`);\n await handler.stop();\n process.exit(0);\n };\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n } else {\n process.exit(0);\n }\n } catch (error) {\n console.error('Failed to start services:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { GatewayService } from '../services/GatewayService.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { consoleLogger } from '../services/logger.js';\n\nconst DEFAULT_SCOPE = 'default';\nconst STATUS_COMMAND_NAME = 'status';\nconst STATUS_COMMAND_DESCRIPTION = 'Show proxy server and profile status';\nconst STATUS_ERROR_MESSAGE = 'Failed to read status';\n\nclass StatusCommandError extends Error {\n readonly code = 'STATUS_CHECK_FAILED';\n\n constructor(cause: unknown) {\n super(STATUS_ERROR_MESSAGE, { cause: cause instanceof Error ? cause : new Error(String(cause)) });\n this.name = 'StatusCommandError';\n }\n}\n\nexport const statusCommand = new Command(STATUS_COMMAND_NAME)\n .description(STATUS_COMMAND_DESCRIPTION)\n .option('-s, --scope <scope>', 'Configuration scope', DEFAULT_SCOPE)\n .action(async (options: { scope: string }) => {\n try {\n const manager = new HttpServerManager();\n const serverStatus = await manager.getStatus();\n const gateway = new GatewayService();\n const status = await gateway.getStatus(options.scope, serverStatus.port, serverStatus.pid);\n status.running = serverStatus.running;\n status.error = serverStatus.error;\n consoleLogger.info(JSON.stringify(status, null, 2));\n process.exit(0);\n } catch (error) {\n const statusError = new StatusCommandError(error);\n consoleLogger.error(STATUS_ERROR_MESSAGE, {\n command: STATUS_COMMAND_NAME,\n code: statusError.code,\n scope: options.scope,\n cause: statusError.cause,\n });\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\n\nexport const stopCommand = new Command('stop').description('Stop the background HTTP server').action(async () => {\n try {\n const manager = new HttpServerManager();\n const stopped = await manager.stop();\n console.log(stopped ? 'HTTP server stopped' : 'No HTTP server running');\n process.exit(0);\n } catch (error) {\n console.error('Failed to stop HTTP server:', error);\n process.exit(1);\n }\n});\n","#!/usr/bin/env node\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport { claudeCommand } from './commands/claude.js';\nimport { httpServeCommand } from './commands/http-serve.js';\nimport { mcpServeCommand } from './commands/mcp-serve.js';\nimport { startCommand } from './commands/start.js';\nimport { statusCommand } from './commands/status.js';\nimport { stopCommand } from './commands/stop.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nasync function main() {\n const program = new Command();\n program.name('model-proxy-mcp').description('Claude-compatible model proxy MCP').version(packageJson.version);\n program.addCommand(startCommand);\n program.addCommand(stopCommand);\n program.addCommand(statusCommand);\n program.addCommand(claudeCommand);\n program.addCommand(httpServeCommand);\n program.addCommand(mcpServeCommand);\n await program.parseAsync(process.argv);\n}\n\nmain();\n"],"mappings":";gpBAMA,IAAa,EAAb,KAAmC,CACjC,MAAM,MAAM,EAA0C,CACpD,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,oBAAoB,EAAK,SAAS,CAM/D,OALK,EAAS,GAKP,CACL,QAAS,GACT,aAHe,MAAM,EAAS,MAAM,EAGf,QACtB,CAPQ,CAAE,QAAS,GAAO,MAAO,mCAAmC,EAAS,SAAU,OAQjF,EAAO,CACd,MAAO,CACL,QAAS,GACT,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D,ICZP,MAAMA,EAAoB,CAAC,sBAAuB,UAAW,OAAO,CAQ9DG,EAA6B,UAC7B,GAAgB,EAAU,EAAS,CAEzC,SAASC,EAAqB,EAAY,QAAQ,KAAK,CAAU,CAC/D,IAAI,EAAa,EAAK,QAAQ,EAAU,CAExC,OAAa,CACX,IAAK,IAAM,KAAUJ,EACnB,GAAI,EAAW,EAAK,KAAK,EAAY,EAAO,CAAC,CAC3C,OAAO,EAIX,IAAM,EAAY,EAAK,QAAQ,EAAW,CAC1C,GAAI,IAAc,EAChB,OAAO,QAAQ,KAAK,CAEtB,EAAa,GAWjB,IAAa,EAAb,KAA+B,CAC7B,eAAkCI,EAAqB,QAAQ,KAAK,CAAC,CACrE,YAA+B,EAC/B,aAEA,YAAY,EAA+B,IAAI,EAAyB,CAA3C,KAAA,YAAA,EAC3B,KAAK,aAAe,IAAI,EAAoB,QAAQ,IAAI,mBAAmB,CAG7E,kBAA0B,EAAoC,EAAE,CAAiB,CAC/E,MAAO,CACL,QAAS,GACT,MAAO,UACP,gBAAiB,KACjB,KAAM,CAAE,WAAY,GAAO,aAAc,GAAI,CAC7C,SAAU,EAAE,CACZ,WAAY,EAAE,CACd,GAAG,EACJ,CAGH,MAAc,iBAAkE,CAC9E,IAAM,EAAS,MAAM,KAAK,aAAa,QAAQ,CAC7C,eAAgB,KAAK,eACrB,YAAa,KAAK,YAClB,YAAaD,EACd,CAAC,CAIF,MAHI,CAAC,EAAO,SAAW,CAAC,EAAO,OACtB,KAEF,CAAE,KAAM,EAAO,OAAO,KAAM,IAAK,EAAO,OAAO,IAAK,CAG7D,MAAc,eAAe,EAA6B,CACxD,MAAM,KAAK,aAAa,YAAY,CAClC,eAAgB,KAAK,eACrB,YAAa,KAAK,YAClB,YAAaA,EACb,MACD,CAAC,CAGJ,MAAc,uBAAuB,EAAuC,CAC1E,GAAI,CACF,GAAM,CAAE,UAAW,MAAM,GAAc,KAAc,CAAC,MAAO,iCAAgC,EAAK,UAAU,CAAE,CAC5G,SAAU,OACX,CAAC,CACF,OAAO,EACJ,MAAM;EAAK,CACX,MAAM,EAAE,CACR,IAAK,GAAS,EAAK,MAAM,CAAC,CAC1B,OAAO,QAAQ,CACf,IAAK,GAAS,EAAK,MAAM,MAAM,CAAC,CAChC,IAAK,IAAW,CACf,IAAK,OAAO,SAAS,EAAM,IAAM,GAAI,GAAG,CACxC,OACD,EAAE,CACF,OAAQ,GAAa,OAAO,UAAU,EAAS,IAAI,EAAI,EAAS,IAAM,EAAE,MACrE,CACN,MAAO,EAAE,EAIb,MAAc,wBAAiD,CAC7D,IAAM,EAAe,MAAM,KAAK,iBAAiB,CACjD,GAAI,EAAc,CAChB,IAAM,EAAS,MAAM,KAAK,YAAY,MAAM,EAAa,KAAK,CAC9D,GAAI,EAAO,SAAW,EAAO,cAAgB,KAAK,YAChD,OAAO,EAAa,KAGxB,OAAO,KAGT,MAAc,mBAAmB,EAAc,EAAqC,CAClF,IAAM,EAAY,MAAM,KAAK,uBAAuB,EAAK,CACzD,IAAK,IAAM,KAAY,EACjB,GAAe,EAAS,MAAQ,GAGpC,MAAM,KAAK,YAAY,EAAS,IAAI,CAIxC,MAAc,gBAAgB,EAAc,EAA4B,CACtE,MAAM,KAAK,aAAa,YAAY,CAClC,eAAgB,KAAK,eACrB,YAAa,KAAK,YAClB,YAAaA,EACb,cAAe,EACf,UAAW,CAAE,IAAK,EAAM,IAAK,EAAM,CACnC,MACA,KAAM,YACN,MAAO,GACR,CAAC,CAGJ,MAAc,kBAAkB,EAAwC,CACtE,IAAM,EAAS,MAAM,KAAK,aAAa,kBAAkB,CACvD,eAAgB,KAAK,eACrB,YAAa,KAAK,YAClB,YAAaA,EACb,KAAM,YACN,gBACA,UAAW,EACZ,CAAC,CACF,GAAI,CAAC,EAAO,SAAW,EAAO,OAAS,IAAA,GACrC,MAAU,MAAM,gCAAgC,IAAgB,CAElE,OAAO,EAAO,KAGhB,MAAc,WAAW,EAAoC,CAC3D,GAAI,CAEF,OADA,MAAME,EAAG,OAAO,EAAS,CAClB,QACD,CACN,MAAO,IAIX,MAAc,gBAAoE,CAChF,IAAM,EAAa,EAAK,QAAQ,EAAc,OAAO,KAAK,IAAI,CAAC,CAGzD,EAAiB,EAAK,QAAQ,EAAY,UAAU,CAC1D,GAAI,MAAM,KAAK,WAAW,EAAe,CACvC,MAAO,CAAE,QAAS,EAAgB,QAAS,OAAQ,CAIrD,IAAM,EAAmB,EAAK,QAAQ,EAAY,KAAM,UAAU,CAClE,GAAI,MAAM,KAAK,WAAW,EAAiB,CACzC,MAAO,CAAE,QAAS,EAAkB,QAAS,OAAQ,CAIvD,IAAM,EAAkB,EAAK,KAAK,KAAK,eAAgB,WAAY,MAAO,kBAAmB,OAAQ,UAAU,CAC/G,GAAI,MAAM,KAAK,WAAW,EAAgB,CACxC,MAAO,CAAE,QAAS,EAAiB,QAAS,OAAQ,CAItD,IAAK,IAAM,IAAW,CAAC,EAAK,QAAQ,EAAY,SAAS,CAAE,EAAK,QAAQ,EAAY,KAAM,SAAS,CAAC,CAClG,GAAI,MAAM,KAAK,WAAW,EAAQ,CAChC,MAAO,CAAE,QAAS,EAAS,QAAS,MAAO,CAI/C,IAAM,EAAiB,EAAK,KAAK,KAAK,eAAgB,WAAY,MAAO,kBAAmB,MAAO,SAAS,CAC5G,GAAI,MAAM,KAAK,WAAW,EAAe,CACvC,MAAO,CAAE,QAAS,EAAgB,QAAS,MAAO,CAGpD,MAAU,MAAM,kCAAkC,CAGpD,MAAc,gBAAgB,EAA+B,CAC3D,GAAM,CAAE,UAAS,WAAY,MAAM,KAAK,gBAAgB,CAQlD,EAAQ,EANE,IAAY,MAAS,QAAQ,SAAS,IAAM,QAAQ,SAAW,MAAS,OAEtF,IAAY,MACR,CAAC,MAAO,EAAS,aAAc,SAAU,OAAO,EAAK,CAAC,CACtD,CAAC,EAAS,aAAc,SAAU,OAAO,EAAK,CAAC,CAElB,CACjC,SAAU,GACV,MAAO,SACP,IAAK,CACH,GAAG,QAAQ,IACX,SAAU,QAAQ,IAAI,UAAY,cACnC,CACF,CAAC,CAGF,GADA,EAAM,OAAO,CACT,CAAC,EAAM,IACT,MAAU,MAAM,8BAA8B,CAGhD,OAAO,EAAM,IAGf,MAAc,YAAY,EAA4B,CACpD,GAAI,CACF,QAAQ,KAAK,EAAK,UAAe,CACjC,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,IAAyB,CAAC,CAC7E,GAAI,CACF,QAAQ,KAAK,EAAK,EAAE,CACpB,QAAQ,KAAK,EAAK,UAAe,MAC3B,CACN,aAEI,CACN,QAIJ,MAAc,eAAe,EAA6D,CACxF,IAAM,EAAW,KAAK,KAAK,CAAG,IAC1B,EAAY,2CAEhB,KAAO,KAAK,KAAK,CAAG,GAAU,CAC5B,IAAM,EAAS,MAAM,KAAK,YAAY,MAAM,EAAK,CACjD,GAAI,EAAO,SAAW,EAAO,cAAgB,KAAK,YAChD,MAAO,CAAE,QAAS,GAAM,CAG1B,EAAY,EAAO,OAAS,8BAA8B,IAC1D,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,IAA8B,CAAC,CAGpF,MAAO,CAAE,QAAS,GAAO,MAAO,EAAW,CAG7C,MAAM,cAAc,EAAO,EAA2C,CACpE,GAAI,CACF,IAAM,EAAc,MAAM,KAAK,wBAAwB,CACvD,GAAI,IAAgB,KAAM,CAExB,IAAM,GADmB,MAAM,KAAK,uBAAuB,EAAY,EACnC,IAAI,IAExC,OADA,MAAM,KAAK,gBAAgB,EAAa,GAAc,QAAQ,IAAI,CAC3D,KAAK,kBAAkB,CAAE,QAAS,GAAM,KAAM,EAAa,IAAK,EAAY,CAAC,CAGtF,IAAM,EAAW,MAAM,KAAK,iBAAiB,CAC7C,GAAI,EAAU,CACZ,IAAMC,EAAS,MAAM,KAAK,YAAY,MAAM,EAAS,KAAK,CAC1D,GAAIA,EAAO,SAAWA,EAAO,cAAgB,KAAK,YAChD,OAAO,KAAK,kBAAkB,CAAE,QAAS,GAAM,KAAM,EAAS,KAAM,IAAK,EAAS,IAAK,CAAC,CAGtF,EAAS,KACX,MAAM,KAAK,YAAY,EAAS,IAAI,CAEtC,MAAM,KAAK,mBAAmB,EAAS,KAAM,EAAS,IAAI,CAC1D,MAAM,KAAK,eAAe,EAAS,IAAI,CAGzC,MAAM,KAAK,mBAAmB,EAAK,CACnC,IAAM,EAAgB,MAAM,KAAK,kBAAkB,EAAK,CAClD,EAAM,MAAM,KAAK,gBAAgB,EAAc,CAC/C,EAAS,MAAM,KAAK,eAAe,EAAc,CASvD,OARK,EAAO,SAOZ,MAAM,KAAK,gBAAgB,EAAe,EAAI,CACvC,KAAK,kBAAkB,CAAE,QAAS,GAAM,KAAM,EAAe,MAAK,CAAC,GAPxE,MAAM,KAAK,YAAY,EAAI,CAC3B,MAAM,KAAK,mBAAmB,EAAe,EAAI,CACjD,MAAM,KAAK,eAAe,EAAI,CACvB,KAAK,kBAAkB,CAAE,MAAO,EAAO,OAAS,2CAA4C,CAAC,QAK/F,EAAO,CACd,OAAO,KAAK,kBAAkB,CAAE,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAE,CAAC,EAIpG,MAAM,MAAyB,CAC7B,IAAM,EAAe,MAAM,KAAK,iBAAiB,CAC7C,EAAU,GAEV,GAAc,MAChB,MAAM,KAAK,YAAY,EAAa,IAAI,CACxC,EAAU,IAER,IACF,MAAM,KAAK,mBAAmB,EAAa,KAAM,EAAa,IAAI,CAClE,MAAM,KAAK,eAAe,EAAa,IAAI,EAG7C,IAAM,EAAc,MAAM,KAAK,wBAAwB,CACvD,GAAI,IAAgB,KAAM,CACxB,IAAM,EAAY,MAAM,KAAK,uBAAuB,EAAY,CAChE,IAAK,IAAM,KAAY,EACrB,MAAM,KAAK,YAAY,EAAS,IAAI,CACpC,EAAU,GAEZ,MAAM,KAAK,gBAAgB,CAG7B,OAAO,EAGT,MAAM,WAAoC,CACxC,IAAM,EAAe,MAAM,KAAK,iBAAiB,CACjD,GAAI,IACa,MAAM,KAAK,YAAY,MAAM,EAAa,KAAK,EACnD,QACT,OAAO,KAAK,kBAAkB,CAC5B,QAAS,GACT,KAAM,EAAa,KACnB,IAAK,EAAa,IACnB,CAAC,CAIN,IAAM,EAAc,MAAM,KAAK,wBAAwB,CACvD,GAAI,IAAgB,KAAM,CAExB,IAAM,GADY,MAAM,KAAK,uBAAuB,EAAY,EAC1C,IAAI,IAI1B,OAHI,GACF,MAAM,KAAK,gBAAgB,EAAa,EAAI,CAEvC,KAAK,kBAAkB,CAC5B,QAAS,GACT,KAAM,EACN,MACD,CAAC,CAGJ,OAAO,KAAK,kBAAkB,CAC5B,MAAO,EAAe,iCAAmC,4BAC1D,CAAC,GC9VN,MAAM,EAAgB,SAKhBE,EAAgC,OAGhC,EAAa,oBACb,EAAmB,iDAAiD,EAAc,gBAaxF,IAAM,EAAN,cAAiC,KAAM,CACrC,YACE,EACA,EACA,EAGA,CACA,MAAM,EAAS,EAAQ,CALd,KAAA,KAAA,EAMT,KAAK,KAAO,uBAIV,EAAN,cAAuC,CAAmB,CACxD,YAAY,EAAiB,EAA+B,CAC1D,MAAM,EAAS,8BAA+B,EAAQ,CACtD,KAAK,KAAO,6BAIV,EAAN,cAA2C,CAAmB,CAC5D,YAAY,EAAiB,EAA+B,CAC1D,MAAM,EAAS,kCAAmC,EAAQ,CAC1D,KAAK,KAAO,iCAIV,EAAN,cAAuC,CAAmB,CACxD,YAAY,EAAiB,EAA+B,CAC1D,MAAM,EAAS,8BAA+B,EAAQ,CACtD,KAAK,KAAO,6BAIhB,SAAgB,EAAc,EAAuB,CAKnD,OAJkB,EACf,MAAM,CACN,QAAQ,oBAAqB,IAAI,CACjC,QAAQ,WAAY,GAAG,EACND,UAGtB,SAAgB,GAA4B,CAC1C,MAAO,SAA0B,GAAY,EAAmB,CAAC,SAAS,MAAM,GAGlF,SAAgB,EACd,EACA,EACA,EAAqC,QAAQ,IAC1B,CACnB,MAAO,CACL,GAAG,EACH,mBAAoB,oBAAoB,EAAK,UAAU,IACvD,6BAA8B,EAAgB,8BAAgC,eAC9E,+BAAgC,EAAgB,gCAAkC,iBAClF,8BAA+B,EAAgB,+BAAiC,gBAChF,2BAA4B,EAAgB,4BAA8B,mBAC1E,sBAAuB,EAAgBE,uBAA0B,EACjE,qBAAsB,EAAgB,sBAAyB,UAChE,CAGH,eAAsB,EACpB,EACA,EAAmB,QAAQ,KAAK,CACH,CAC7B,IAAM,EAAY,EACd,EAAK,QAAQ,EAAkB,EAAW,CAC1C,EAAK,KAAK,EAAkB,uBAAwB,CAExD,GAAI,CAEF,GAAI,EADU,MAAME,EAAG,KAAK,EAAU,EAC3B,QAAQ,CAAE,CACnB,GAAI,EACF,MAAM,IAAI,EAAyB,yCAAyC,IAAY,CAE1F,OAEF,OAAO,QACA,EAAO,CAEd,GADkB,EACJ,OAAS,SAAU,CAC/B,GAAI,EACF,MAAM,IAAI,EAAyB,qCAAqC,IAAa,CAAE,MAAO,EAAO,CAAC,CAExG,OAKF,MAHI,aAAiB,EACb,EAEF,IAAI,EAAyB,0CAA0C,IAAa,CAAE,MAAO,EAAO,CAAC,EAI/G,SAAS,GAA+B,CACtC,IAAM,EAAgB,QAAQ,IAAI,MAAQ,QAAQ,IAAI,YACtD,GAAI,CAAC,EACH,MAAM,IAAI,EAAyB,iCAAiC,CAGtE,OAAO,EAAK,KAAK,EAAe,mBAAwB,CAG1D,eAAe,GAA2C,CACxD,IAAM,EAAoB,GAAsB,CAEhD,OADA,MAAMA,EAAG,MAAM,EAAmB,CAAE,UAAW,GAAM,CAAC,CAC/C,EAGT,eAAe,EAAc,EAA6C,CACxE,GAAI,CAEF,OADmB,MAAMA,EAAG,SAAS,EAAa,EAAc,EAAE,MAAM,EACpD,WACb,EAAO,CAEd,GADkB,EACJ,OAAS,SACrB,OAAO,KAET,MAAM,IAAI,EAAyB,uCAAuC,IAAe,CAAE,MAAO,EAAO,CAAC,EAI9G,eAAe,EAAiB,EAAe,EAAwE,CACrH,IAAM,EAAoB,MAAM,GAAyB,CACnD,EAAc,EAAK,KAAK,EAAmB,EAAM,CAEvD,GAAI,EACF,GAAI,CACF,MAAMA,EAAG,GAAG,EAAa,CAAE,MAAO,GAAM,CAAC,OAClC,EAAO,CACd,MAAM,IAAI,EAAyB,wCAAwC,IAAe,CAAE,MAAO,EAAO,CAAC,CAI/G,IAAM,EAAoB,MAAM,EAAc,EAAY,CAC1D,GAAI,EACF,MAAO,CAAE,UAAW,EAAmB,OAAQ,GAAM,CAGvD,IAAM,EAAY,GAAY,CAAC,aAAa,CAC5C,GAAI,CACF,MAAMA,EAAG,UAAU,EAAa,GAAG,EAAU,IAAK,EAAc,OACzD,EAAO,CACd,MAAM,IAAI,EAAyB,wCAAwC,IAAe,CAAE,MAAO,EAAO,CAAC,CAE7G,MAAO,CAAE,YAAW,OAAQ,GAAO,CAGrC,eAAe,EACb,EACA,EACA,EACA,EACA,EACiB,CACjB,IAAM,EAAsB,MAAM,EAA2B,EAAW,CAExE,MADqB,IAAI,GAAc,CACpB,aAAa,EAAO,EAAoB,CAG3D,IAAM,EAAS,MADO,IAAI,GAAmB,CACV,cAAc,EAAK,CAEtD,GAAI,CAAC,EAAO,SAAW,CAAC,EAAO,KAC7B,MAAM,IAAI,EAAyB,EAAO,OAAS,0CAA0C,CAG/F,GAAM,CAAE,YAAW,UAAW,MAAM,EAAiB,EAAO,EAAa,CACnE,EAAM,EAAuB,EAAO,KAAM,EAAM,CAChD,EAAO,CACX,iCACA,GAAI,EAAS,CAAC,WAAY,EAAU,CAAG,CAAC,eAAgB,EAAU,CAClE,GAAG,EACJ,CASD,OAPA,QAAQ,IAAI,GAAG,EAAW,UAAU,IAAQ,CAC5C,QAAQ,IAAI,GAAG,EAAW,UAAU,EAAI,qBAAqB,CAC7D,QAAQ,IAAI,GAAG,EAAW,YAAY,IAAY,EAAS,YAAc,WAAW,CAChF,GACF,QAAQ,IAAI,GAAG,EAAW,sBAAsB,IAAsB,CAGjE,IAAI,SAAiB,EAAS,IAAW,CAC9C,IAAM,EAAQ,EAAM,EAAe,EAAM,CACvC,MAAO,UACP,MACD,CAAC,CAEF,EAAM,GAAG,QAAU,GAAU,CAC3B,EACE,IAAI,EAAyB,oBAAoB,IAAiB,CAChE,MAAO,EACR,CAAC,CACH,EACD,CAEF,EAAM,GAAG,QAAS,EAAM,IAAW,CACjC,GAAI,EAAQ,CACV,EAAO,IAAI,EAAyB,GAAG,EAAc,sBAAsB,IAAS,CAAC,CACrF,OAEF,EAAQ,GAAQ,EAAE,EAClB,EACF,CAGJ,MAAa,EAAgB,IAAI,EAAQ,SAAS,CAC/C,YAAY,6CAA6C,CACzD,OAAO,sBAAuB,qBAAqB,CACnD,OAAO,oBAAqB,oCAAqC,OAAO,EAAkB,CAAC,CAC3F,OAAO,2BAA4B,wDAAwD,CAC3F,OAAO,kBAAmB,0BAA0B,CACpD,OAAO,kBAAmB,2DAA4D,GAAM,CAC5F,mBAAmB,GAAK,CACxB,qBAAqB,GAAK,CAC1B,SAAS,kBAAkB,CAC3B,OACC,MACE,EACA,IACG,CACH,GAAI,CACF,IAAM,EAAgB,EAAc,EAAQ,OAAS,GAAmB,CAAC,CACnE,EAAO,OAAO,SAAS,EAAQ,KAAM,GAAc,CACzD,GAAI,CAAC,OAAO,UAAU,EAAK,EAAI,GAAQ,EACrC,MAAM,IAAI,EAA6B,iBAAiB,EAAQ,OAAO,CAGzE,IAAM,EAAW,MAAM,EACrB,EACA,EACA,EAAQ,aACR,EACA,EAAQ,YAAc,EAAQ,OAC/B,CACD,QAAQ,KAAK,EAAS,OACf,EAAO,CACd,IAAM,EACJ,aAAiB,EACb,EACA,IAAI,EAAyB,0BAA2B,CAAE,MAAO,EAAO,CAAC,CAC/E,QAAQ,MAAM,GAAG,EAAW,GAAG,EAAa,KAAK,IAAI,EAAa,UAAU,CAC5E,QAAQ,MAAM,GAAG,EAAW,GAAG,IAAmB,CAC9C,EAAa,OACf,QAAQ,MAAM,GAAG,EAAW,SAAU,EAAa,MAAM,CAE3D,QAAQ,KAAK,EAAE,GAGpB,CC9QG,EAAa,YACb,EAAoB,CAAC,sBAAuB,UAAW,OAAO,CAC9D,EAA6B,UAInC,SAAS,EAAqB,EAAY,QAAQ,KAAK,CAAU,CAC/D,IAAI,EAAU,EAAK,QAAQ,EAAU,CACrC,OAAa,CACX,IAAK,IAAM,KAAU,EACnB,GAAI,EAAW,EAAK,KAAK,EAAS,EAAO,CAAC,CACxC,OAAO,EAGX,IAAM,EAAS,EAAK,QAAQ,EAAQ,CACpC,GAAI,IAAW,EACb,OAAO,QAAQ,KAAK,CAEtB,EAAU,GAId,MAAa,EAAmB,IAAI,EAAQ,aAAa,CACtD,YAAY,sDAAsD,CAClE,OAAO,oBAAqB,oBAAqB,OAAO,EAAkB,CAAC,CAC3E,OAAO,KAAO,IAA8B,CAC3C,IAAIC,EACJ,GAAI,CACF,IAAM,EAAgB,OAAO,SAAS,EAAQ,KAAM,GAAG,CACvD,GAAI,CAAC,OAAO,UAAU,EAAc,EAAI,GAAiB,EACvD,MAAU,MAAM,iBAAiB,EAAQ,OAAO,CAGlD,IAAM,EAAe,IAAI,EAAoB,QAAQ,IAAI,mBAAmB,CACtE,EAAiB,GAAsB,CACvC,EAAgB,MAAM,EAAa,YAAY,CACnD,iBACA,YAAa,EACb,YAAa,EACb,cAAe,EACf,UAAW,EACX,IAAK,QAAQ,IACb,KAAM,EACN,MAAO,GACR,CAAC,CAEF,GAAI,CAAC,EAAc,SAAW,CAAC,EAAc,OAC3C,MAAU,MAAM,EAAc,OAAS,0BAA0B,IAAgB,CAGnF,IAAM,EAAO,EAAc,OAAO,KAElC,EAAe,MAAM,EAAmB,CACtC,iBACA,YAAa,EACb,YAAa,EACb,IAAK,QAAQ,IACb,OACA,KAAM,EACN,QAAS,QAAQ,KAAK,GACtB,KAAM,QAAQ,KAAK,MAAM,EAAE,CAC5B,CAAC,CAEF,IAAM,EAAiB,IAAI,EAC3B,MAAM,EAAe,cAAc,CAEnC,IAAM,EAAS,EAAM,CAAE,MADX,EAAiB,EAAe,CACV,MAAO,OAAM,SAAU,EAAY,CAAC,CAEtE,QAAQ,IAAI,uCAAuC,EAAW,GAAG,IAAO,CACxE,QAAQ,IAAI,2BAA2B,EAAW,GAAG,IAAO,CAE5D,IAAM,EAAW,KAAO,IAAmB,CACzC,QAAQ,IAAI,KAAK,EAAO,6BAA6B,CACrD,EAAO,OAAO,CACd,MAAM,GAAc,SAAS,CAC7B,MAAM,EAAa,YAAY,CAC7B,iBACA,YAAa,EACb,YAAa,EACb,IAAK,QAAQ,IACd,CAAC,CACF,QAAQ,KAAK,EAAE,EAGjB,QAAQ,KAAK,aAAgB,EAAS,SAAS,CAAC,CAChD,QAAQ,KAAK,cAAiB,EAAS,UAAU,CAAC,OAC3C,EAAO,CACd,MAAM,GAAc,SAAS,CAC7B,QAAQ,MAAM,+BAAgC,EAAM,CACpD,QAAQ,KAAK,EAAE,GAEjB,CCzFS,GAAkB,IAAI,EAAQ,YAAY,CACpD,YAAY,wCAAwC,CACpD,OAAO,YAAa,+BAAgC,GAAM,CAC1D,OAAO,oBAAqB,uBAAwB,OAAO,EAAkB,CAAC,CAC9E,OAAO,KAAO,IAA6B,CAC1C,GAAI,CACF,IAAM,EAAO,OAAO,SAAS,EAAQ,KAAM,GAAG,CAC9C,GAAI,CAAC,OAAO,UAAU,EAAK,EAAI,GAAQ,EACrC,MAAU,MAAM,iBAAiB,EAAQ,OAAO,CAGlD,IAAM,EAAiB,IAAI,EAC3B,MAAM,EAAe,aAAa,QAAQ,IAAI,uBAA0BC,UAAc,CAEtF,IAAM,EAAU,IAAI,EACd,EAAa,MAAM,EAAQ,cAAc,EAAK,CAC/C,EAAW,SACd,QAAQ,MAAM,yCAAyC,EAAW,QAAQ,CAG5E,IAAM,EAAU,IAAI,EAAsB,EAAa,EAAe,CAAC,CAEjE,EAAW,KAAO,IAAmB,CACzC,QAAQ,MAAM,cAAc,EAAO,+BAA+B,CAClE,MAAM,EAAQ,MAAM,CAChB,EAAQ,SAAW,EAAW,SAChC,MAAM,EAAQ,MAAM,CAEtB,QAAQ,KAAK,EAAE,EAGjB,QAAQ,KACN,aAEE,KAAK,EAAS,SAAS,CAAC,MAAO,GAAU,CACvC,QAAQ,MAAM,oCAAqC,EAAM,CACzD,QAAQ,KAAK,EAAE,EACf,CACL,CACD,QAAQ,KACN,cAEE,KAAK,EAAS,UAAU,CAAC,MAAO,GAAU,CACxC,QAAQ,MAAM,qCAAsC,EAAM,CAC1D,QAAQ,KAAK,EAAE,EACf,CACL,CAED,MAAM,EAAQ,OAAO,OACd,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAM,CACnD,QAAQ,KAAK,EAAE,GAEjB,CC3DS,GAAe,IAAI,EAAQ,QAAQ,CAC7C,YAAY,mDAAmD,CAC/D,OAAO,aAAc,4BAA6B,GAAM,CACxD,OAAO,cAAe,6BAA8B,GAAM,CAC1D,OAAO,oBAAqB,uBAAwB,OAAO,EAAkB,CAAC,CAC9E,OAAO,KAAO,IAAY,CACzB,GAAI,CACF,IAAM,EAAoB,IAAI,EACxB,EAAO,OAAO,SAAS,EAAQ,KAAM,GAAG,CACxC,EAAY,CAAC,EAAQ,QACrB,EAAW,CAAC,EAAQ,SAE1B,GAAI,EAAW,CACb,IAAM,EAAS,MAAM,EAAkB,cAAc,EAAK,CACrD,EAAO,UACV,QAAQ,MAAM,gCAAgC,EAAO,QAAQ,CAC7D,QAAQ,KAAK,EAAE,EAEjB,QAAQ,IAAI,2CAA2C,EAAO,OAAO,CAGvE,GAAI,EAAU,CACZ,IAAM,EAAU,IAAI,EAAsB,GAAc,CAAC,CACzD,MAAM,EAAQ,OAAO,CACrB,IAAM,EAAW,KAAO,IAAmB,CACzC,QAAQ,MAAM,KAAK,EAAO,6BAA6B,CACvD,MAAM,EAAQ,MAAM,CACpB,QAAQ,KAAK,EAAE,EAEjB,QAAQ,GAAG,aAAgB,EAAS,SAAS,CAAC,CAC9C,QAAQ,GAAG,cAAiB,EAAS,UAAU,CAAC,MAEhD,QAAQ,KAAK,EAAE,OAEV,EAAO,CACd,QAAQ,MAAM,4BAA6B,EAAM,CACjD,QAAQ,KAAK,EAAE,GAEjB,CCtCE,EAAsB,SAEtB,EAAuB,wBAE7B,IAAM,GAAN,cAAiC,KAAM,CACrC,KAAgB,sBAEhB,YAAY,EAAgB,CAC1B,MAAM,EAAsB,CAAE,MAAO,aAAiB,MAAQ,EAAY,MAAM,OAAO,EAAM,CAAC,CAAE,CAAC,CACjG,KAAK,KAAO,uBAIhB,MAAa,GAAgB,IAAI,EAAQ,EAAoB,CAC1D,YAAY,uCAA2B,CACvC,OAAO,sBAAuB,sBAAuB,UAAc,CACnE,OAAO,KAAO,IAA+B,CAC5C,GAAI,CAEF,IAAM,EAAe,MADL,IAAI,GAAmB,CACJ,WAAW,CAExC,EAAS,MADC,IAAI,GAAgB,CACP,UAAU,EAAQ,MAAO,EAAa,KAAM,EAAa,IAAI,CAC1F,EAAO,QAAU,EAAa,QAC9B,EAAO,MAAQ,EAAa,MAC5B,EAAc,KAAK,KAAK,UAAU,EAAQ,KAAM,EAAE,CAAC,CACnD,QAAQ,KAAK,EAAE,OACR,EAAO,CACd,IAAM,EAAc,IAAI,GAAmB,EAAM,CACjD,EAAc,MAAM,EAAsB,CACxC,QAAS,EACT,KAAM,EAAY,KAClB,MAAO,EAAQ,MACf,MAAO,EAAY,MACpB,CAAC,CACF,QAAQ,KAAK,EAAE,GAEjB,CCvCS,GAAc,IAAI,EAAQ,OAAO,CAAC,YAAY,kCAAkC,CAAC,OAAO,SAAY,CAC/G,GAAI,CAEF,IAAM,EAAU,MADA,IAAI,GAAmB,CACT,MAAM,CACpC,QAAQ,IAAI,EAAU,sBAAwB,yBAAyB,CACvE,QAAQ,KAAK,EAAE,OACR,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAM,CACnD,QAAQ,KAAK,EAAE,GAEjB,CCDI,GAAY,EAAQ,EAAc,OAAO,KAAK,IAAI,CAAC,CACnD,GAAc,KAAK,MAAM,EAAa,EAAK,GAAW,kBAAkB,CAAE,QAAQ,CAAC,CAEzF,eAAe,IAAO,CACpB,IAAM,EAAU,IAAI,EACpB,EAAQ,KAAK,kBAAkB,CAAC,YAAY,oCAAoC,CAAC,QAAQ,GAAY,QAAQ,CAC7G,EAAQ,WAAW,GAAa,CAChC,EAAQ,WAAW,GAAY,CAC/B,EAAQ,WAAW,GAAc,CACjC,EAAQ,WAAW,EAAc,CACjC,EAAQ,WAAW,EAAiB,CACpC,EAAQ,WAAW,GAAgB,CACnC,MAAM,EAAQ,WAAW,QAAQ,KAAK,CAGxC,IAAM"}
1
+ {"version":3,"file":"cli.mjs","names":["WORKSPACE_MARKERS","PORT_REGISTRY_SERVICE_TYPE","resolveWorkspaceRoot","fs","DEFAULT_SCOPE","MODEL_PROXY_SCOPE_ENV","fs","DEFAULT_SCOPE"],"sources":["../src/services/HttpServerHealthCheck.ts","../src/services/HttpServerManager.ts","../src/commands/claude.ts","../src/commands/http-serve.ts","../src/commands/mcp-serve.ts","../src/commands/start.ts","../src/commands/status.ts","../src/commands/stop.ts","../src/cli.ts"],"sourcesContent":["export interface HealthCheckResult {\n healthy: boolean;\n serviceName?: string;\n error?: string;\n}\n\nexport class HttpServerHealthCheck {\n async check(port: number): Promise<HealthCheckResult> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`);\n if (!response.ok) {\n return { healthy: false, error: `Health check failed with status ${response.status}` };\n }\n\n const payload = (await response.json()) as { service?: string };\n return {\n healthy: true,\n serviceName: payload.service,\n };\n } catch (error) {\n return {\n healthy: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n}\n","import { execFile, spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { promisify } from 'node:util';\nimport { PortRegistryService } from '@agimon-ai/foundation-port-registry';\nimport { DEFAULT_HTTP_PORT, DEFAULT_SERVICE_NAME, MODEL_PROXY_PORT_RANGE } from '../constants/defaults.js';\nimport type { GatewayStatus } from '../types/index.js';\nimport { HttpServerHealthCheck } from './HttpServerHealthCheck.js';\n\nconst WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'nx.json', '.git'];\nconst SHELL_BINARY = 'sh';\nconst LSOF_COMMAND_PREFIX = 'lsof -n -P -sTCP:LISTEN';\nconst HEALTH_CHECK_STABILIZE_MS = 5000;\nconst HEALTH_CHECK_POLL_INTERVAL_MS = 250;\nconst PROCESS_SHUTDOWN_WAIT_MS = 1000;\nconst SIGTERM_SIGNAL: NodeJS.Signals = 'SIGTERM';\nconst SIGKILL_SIGNAL: NodeJS.Signals = 'SIGKILL';\nconst PORT_REGISTRY_SERVICE_TYPE = 'service' as const;\nconst execFileAsync = promisify(execFile);\n\nfunction resolveWorkspaceRoot(startPath = process.cwd()): string {\n let currentDir = path.resolve(startPath);\n\n while (true) {\n for (const marker of WORKSPACE_MARKERS) {\n if (existsSync(path.join(currentDir, marker))) {\n return currentDir;\n }\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n return process.cwd();\n }\n currentDir = parentDir;\n }\n}\n\ninterface PortListener {\n port: number;\n pid: number;\n}\n\ntype CliRuntime = 'node' | 'bun';\n\nexport class HttpServerManager {\n private readonly repositoryPath = resolveWorkspaceRoot(process.cwd());\n private readonly serviceName = DEFAULT_SERVICE_NAME;\n private readonly portRegistry: PortRegistryService;\n\n constructor(private readonly healthCheck = new HttpServerHealthCheck()) {\n this.portRegistry = new PortRegistryService(process.env.PORT_REGISTRY_PATH);\n }\n\n private createEmptyStatus(overrides: Partial<GatewayStatus> = {}): GatewayStatus {\n return {\n running: false,\n scope: 'default',\n activeProfileId: null,\n auth: { configured: false, authFilePath: '' },\n profiles: [],\n slotModels: {},\n ...overrides,\n };\n }\n\n private async getRegistration(): Promise<{ port: number; pid?: number } | null> {\n const result = await this.portRegistry.getPort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n });\n if (!result.success || !result.record) {\n return null;\n }\n return { port: result.record.port, pid: result.record.pid };\n }\n\n private async releaseService(pid?: number): Promise<void> {\n await this.portRegistry.releasePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid,\n });\n }\n\n private async listListeningProcesses(port: number): Promise<PortListener[]> {\n try {\n const { stdout } = await execFileAsync(SHELL_BINARY, ['-lc', `${LSOF_COMMAND_PREFIX} -iTCP:${port} || true`], {\n encoding: 'utf8',\n });\n return stdout\n .split('\\n')\n .slice(1)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => line.split(/\\s+/))\n .map((parts) => ({\n pid: Number.parseInt(parts[1] || '', 10),\n port,\n }))\n .filter((listener) => Number.isInteger(listener.pid) && listener.pid > 0);\n } catch {\n return [];\n }\n }\n\n private async findHealthyServicePort(): Promise<number | null> {\n const registration = await this.getRegistration();\n if (registration) {\n const health = await this.healthCheck.check(registration.port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return registration.port;\n }\n }\n return null;\n }\n\n private async clearPortListeners(port: number, preservePid?: number): Promise<void> {\n const listeners = await this.listListeningProcesses(port);\n for (const listener of listeners) {\n if (preservePid && listener.pid === preservePid) {\n continue;\n }\n await this.killProcess(listener.pid);\n }\n }\n\n private async registerService(port: number, pid: number): Promise<void> {\n await this.portRegistry.reservePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n preferredPort: port,\n portRange: { min: port, max: port },\n pid,\n host: '127.0.0.1',\n force: true,\n });\n }\n\n private async findAvailablePort(preferredPort: number): Promise<number> {\n const result = await this.portRegistry.findAvailablePort({\n repositoryPath: this.repositoryPath,\n serviceName: this.serviceName,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n host: '127.0.0.1',\n preferredPort,\n portRange: MODEL_PROXY_PORT_RANGE,\n });\n if (!result.success || result.port === undefined) {\n throw new Error(`No available port found from ${preferredPort}`);\n }\n return result.port;\n }\n\n private async fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n private async resolveCliPath(): Promise<{ cliPath: string; runtime: CliRuntime }> {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n\n // Bundled dist output: cli.mjs lives in the same directory as this file\n const sameDirCliPath = path.resolve(currentDir, 'cli.mjs');\n if (await this.fileExists(sameDirCliPath)) {\n return { cliPath: sameDirCliPath, runtime: 'node' };\n }\n\n // Unbundled dist output: this file is in dist/services/, cli.mjs is in dist/\n const parentDirCliPath = path.resolve(currentDir, '..', 'cli.mjs');\n if (await this.fileExists(parentDirCliPath)) {\n return { cliPath: parentDirCliPath, runtime: 'node' };\n }\n\n // Workspace fallbacks for monorepo development\n const repoDistCliPath = path.join(this.repositoryPath, 'packages', 'mcp', 'model-proxy-mcp', 'dist', 'cli.mjs');\n if (await this.fileExists(repoDistCliPath)) {\n return { cliPath: repoDistCliPath, runtime: 'node' };\n }\n\n // Dev mode: source cli.ts next to this file or one level up\n for (const relPath of [path.resolve(currentDir, 'cli.ts'), path.resolve(currentDir, '..', 'cli.ts')]) {\n if (await this.fileExists(relPath)) {\n return { cliPath: relPath, runtime: 'bun' };\n }\n }\n\n const repoSrcCliPath = path.join(this.repositoryPath, 'packages', 'mcp', 'model-proxy-mcp', 'src', 'cli.ts');\n if (await this.fileExists(repoSrcCliPath)) {\n return { cliPath: repoSrcCliPath, runtime: 'bun' };\n }\n\n throw new Error('Cannot find model-proxy-mcp CLI');\n }\n\n private async startHttpServer(port: number): Promise<number> {\n const { cliPath, runtime } = await this.resolveCliPath();\n\n const command = runtime === 'bun' ? (process.versions.bun ? process.execPath : 'bun') : 'node';\n const args =\n runtime === 'bun'\n ? ['run', cliPath, 'http-serve', '--port', String(port)]\n : [cliPath, 'http-serve', '--port', String(port)];\n\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: process.env.NODE_ENV || 'development',\n },\n });\n\n child.unref();\n if (!child.pid) {\n throw new Error('Failed to spawn HTTP server');\n }\n\n return child.pid;\n }\n\n private async killProcess(pid: number): Promise<void> {\n try {\n process.kill(pid, SIGTERM_SIGNAL);\n await new Promise((resolve) => setTimeout(resolve, PROCESS_SHUTDOWN_WAIT_MS));\n try {\n process.kill(pid, 0);\n process.kill(pid, SIGKILL_SIGNAL);\n } catch {\n return;\n }\n } catch {\n return;\n }\n }\n\n private async waitForHealthy(port: number): Promise<{ healthy: boolean; error?: string }> {\n const deadline = Date.now() + HEALTH_CHECK_STABILIZE_MS;\n let lastError = 'Server failed health check after startup';\n\n while (Date.now() < deadline) {\n const health = await this.healthCheck.check(port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return { healthy: true };\n }\n\n lastError = health.error || `Unexpected service on port ${port}`;\n await new Promise((resolve) => setTimeout(resolve, HEALTH_CHECK_POLL_INTERVAL_MS));\n }\n\n return { healthy: false, error: lastError };\n }\n\n async ensureRunning(port = DEFAULT_HTTP_PORT): Promise<GatewayStatus> {\n try {\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const healthyListeners = await this.listListeningProcesses(healthyPort);\n const healthyPid = healthyListeners[0]?.pid;\n await this.registerService(healthyPort, healthyPid ?? process.pid);\n return this.createEmptyStatus({ running: true, port: healthyPort, pid: healthyPid });\n }\n\n const existing = await this.getRegistration();\n if (existing) {\n const health = await this.healthCheck.check(existing.port);\n if (health.healthy && health.serviceName === this.serviceName) {\n return this.createEmptyStatus({ running: true, port: existing.port, pid: existing.pid });\n }\n\n if (existing.pid) {\n await this.killProcess(existing.pid);\n }\n await this.clearPortListeners(existing.port, existing.pid);\n await this.releaseService(existing.pid);\n }\n\n await this.clearPortListeners(port);\n const availablePort = await this.findAvailablePort(port);\n const pid = await this.startHttpServer(availablePort);\n const health = await this.waitForHealthy(availablePort);\n if (!health.healthy) {\n await this.killProcess(pid);\n await this.clearPortListeners(availablePort, pid);\n await this.releaseService(pid);\n return this.createEmptyStatus({ error: health.error || 'Server failed health check after startup' });\n }\n\n await this.registerService(availablePort, pid);\n return this.createEmptyStatus({ running: true, port: availablePort, pid });\n } catch (error) {\n return this.createEmptyStatus({ error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n /**\n * Start a periodic health monitor that restarts the HTTP server if it goes down.\n * Uses exponential backoff on consecutive failures.\n * Returns a stop function to cancel monitoring on shutdown.\n */\n startHealthMonitor(port: number, intervalMs = 10_000): () => void {\n let stopped = false;\n let consecutiveFailures = 0;\n const BASE_DELAY_MS = 2_000;\n const MAX_DELAY_MS = 60_000;\n\n const check = async (): Promise<void> => {\n if (stopped) return;\n try {\n const status = await this.getStatus();\n if (!status.running) {\n consecutiveFailures++;\n const backoff = Math.min(BASE_DELAY_MS * 2 ** (consecutiveFailures - 1), MAX_DELAY_MS);\n await this.ensureRunning(port);\n if (!stopped) setTimeout(() => void check(), backoff);\n } else {\n consecutiveFailures = 0;\n if (!stopped) setTimeout(() => void check(), intervalMs);\n }\n } catch {\n consecutiveFailures++;\n const backoff = Math.min(BASE_DELAY_MS * 2 ** (consecutiveFailures - 1), MAX_DELAY_MS);\n if (!stopped) setTimeout(() => void check(), backoff);\n }\n };\n\n setTimeout(() => void check(), intervalMs);\n return () => {\n stopped = true;\n };\n }\n\n async stop(): Promise<boolean> {\n const registration = await this.getRegistration();\n let stopped = false;\n\n if (registration?.pid) {\n await this.killProcess(registration.pid);\n stopped = true;\n }\n if (registration) {\n await this.clearPortListeners(registration.port, registration.pid);\n await this.releaseService(registration.pid);\n }\n\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const listeners = await this.listListeningProcesses(healthyPort);\n for (const listener of listeners) {\n await this.killProcess(listener.pid);\n stopped = true;\n }\n await this.releaseService();\n }\n\n return stopped;\n }\n\n async getStatus(): Promise<GatewayStatus> {\n const registration = await this.getRegistration();\n if (registration) {\n const health = await this.healthCheck.check(registration.port);\n if (health.healthy) {\n return this.createEmptyStatus({\n running: true,\n port: registration.port,\n pid: registration.pid,\n });\n }\n }\n\n const healthyPort = await this.findHealthyServicePort();\n if (healthyPort !== null) {\n const listeners = await this.listListeningProcesses(healthyPort);\n const pid = listeners[0]?.pid;\n if (pid) {\n await this.registerService(healthyPort, pid);\n }\n return this.createEmptyStatus({\n running: true,\n port: healthyPort,\n pid,\n });\n }\n\n return this.createEmptyStatus({\n error: registration ? 'Registered server is unhealthy' : 'No HTTP server registered',\n });\n }\n}\n","import { spawn } from 'node:child_process';\nimport { randomBytes, randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { ProfileStore } from '../services/ProfileStore.js';\n\nconst CLAUDE_BINARY = 'claude';\nconst DEFAULT_SCOPE = 'default';\nconst SESSIONS_DIRECTORY_NAME = '.claude-sessions';\nconst RANDOM_SCOPE_PREFIX = 'scope';\nconst RANDOM_SCOPE_BYTES = 3;\nconst TEXT_ENCODING: BufferEncoding = 'utf8';\nconst STDIO_INHERIT = 'inherit';\nconst DECIMAL_RADIX = 10;\nconst LOG_PREFIX = '[model-proxy-mcp]';\nconst RECOVERY_MESSAGE = `Recovery: verify HOME, proxy port, and that \\`${CLAUDE_BINARY}\\` is on PATH.`;\nconst ARG_RESUME = '--resume';\nconst ARG_SESSION_ID = '--session-id';\nconst ARG_SKIP_PERMISSIONS = '--dangerously-skip-permissions';\nconst MODEL_ALIAS_OPUS = 'ccproxy-opus';\nconst MODEL_ALIAS_SONNET = 'ccproxy-sonnet';\nconst MODEL_ALIAS_HAIKU = 'ccproxy-haiku';\nconst MODEL_ALIAS_SUBAGENT = 'ccproxy-subagent';\nconst DEFAULT_SCOPE_SEED_FILE = 'model-proxy-mcp.yaml';\nconst MODEL_PROXY_SCOPE_ENV = 'MODEL_PROXY_MCP_SCOPE';\nconst MODEL_PROXY_SLOT_ENV = 'MODEL_PROXY_MCP_SLOT';\nconst DEFAULT_MODEL_PROXY_SLOT = 'default';\n\nclass ClaudeCommandError extends Error {\n constructor(\n message: string,\n readonly code: string,\n options?: {\n cause?: unknown;\n },\n ) {\n super(message, options);\n this.name = 'ClaudeCommandError';\n }\n}\n\nclass ClaudeCommandConfigError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_CONFIG_ERROR', options);\n this.name = 'ClaudeCommandConfigError';\n }\n}\n\nclass ClaudeCommandValidationError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_VALIDATION_ERROR', options);\n this.name = 'ClaudeCommandValidationError';\n }\n}\n\nclass ClaudeCommandLaunchError extends ClaudeCommandError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, 'CLAUDE_COMMAND_LAUNCH_ERROR', options);\n this.name = 'ClaudeCommandLaunchError';\n }\n}\n\nexport function sanitizeScope(scope: string): string {\n const sanitized = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return sanitized || DEFAULT_SCOPE;\n}\n\nexport function generateScopeName(): string {\n return `${RANDOM_SCOPE_PREFIX}-${randomBytes(RANDOM_SCOPE_BYTES).toString('hex')}`;\n}\n\nexport function buildClaudeEnvironment(\n port: number,\n scope: string,\n baseEnvironment: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n return {\n ...baseEnvironment,\n ANTHROPIC_BASE_URL: `http://127.0.0.1:${port}/scopes/${scope}`,\n ANTHROPIC_DEFAULT_OPUS_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_OPUS_MODEL || MODEL_ALIAS_OPUS,\n ANTHROPIC_DEFAULT_SONNET_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_SONNET_MODEL || MODEL_ALIAS_SONNET,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: baseEnvironment.ANTHROPIC_DEFAULT_HAIKU_MODEL || MODEL_ALIAS_HAIKU,\n CLAUDE_CODE_SUBAGENT_MODEL: baseEnvironment.CLAUDE_CODE_SUBAGENT_MODEL || MODEL_ALIAS_SUBAGENT,\n MODEL_PROXY_MCP_SCOPE: baseEnvironment[MODEL_PROXY_SCOPE_ENV] || scope,\n MODEL_PROXY_MCP_SLOT: baseEnvironment[MODEL_PROXY_SLOT_ENV] || DEFAULT_MODEL_PROXY_SLOT,\n };\n}\n\nexport async function resolveScopeSeedConfigPath(\n configFile: string | undefined,\n workingDirectory = process.cwd(),\n): Promise<string | undefined> {\n const candidate = configFile\n ? path.resolve(workingDirectory, configFile)\n : path.join(workingDirectory, DEFAULT_SCOPE_SEED_FILE);\n\n try {\n const stats = await fs.stat(candidate);\n if (!stats.isFile()) {\n if (configFile) {\n throw new ClaudeCommandConfigError(`Scope seed config path is not a file: ${candidate}`);\n }\n return undefined;\n }\n return candidate;\n } catch (error) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code === 'ENOENT') {\n if (configFile) {\n throw new ClaudeCommandConfigError(`Scope seed config file not found: ${candidate}`, { cause: error });\n }\n return undefined;\n }\n if (error instanceof ClaudeCommandConfigError) {\n throw error;\n }\n throw new ClaudeCommandConfigError(`Failed to read scope seed config file: ${candidate}`, { cause: error });\n }\n}\n\nfunction getSessionsDirectory(): string {\n const homeDirectory = process.env.HOME || process.env.USERPROFILE;\n if (!homeDirectory) {\n throw new ClaudeCommandConfigError('HOME or USERPROFILE is not set');\n }\n\n return path.join(homeDirectory, SESSIONS_DIRECTORY_NAME);\n}\n\nasync function ensureSessionsDirectory(): Promise<string> {\n const sessionsDirectory = getSessionsDirectory();\n await fs.mkdir(sessionsDirectory, { recursive: true });\n return sessionsDirectory;\n}\n\nasync function readSessionId(sessionFile: string): Promise<string | null> {\n try {\n const sessionId = (await fs.readFile(sessionFile, TEXT_ENCODING)).trim();\n return sessionId || null;\n } catch (error) {\n const nodeError = error as NodeJS.ErrnoException;\n if (nodeError.code === 'ENOENT') {\n return null;\n }\n throw new ClaudeCommandConfigError(`Failed to read Claude session file: ${sessionFile}`, { cause: error });\n }\n}\n\nasync function resolveSessionId(scope: string, clearSession: boolean): Promise<{ sessionId: string; resume: boolean }> {\n const sessionsDirectory = await ensureSessionsDirectory();\n const sessionFile = path.join(sessionsDirectory, scope);\n\n if (clearSession) {\n try {\n await fs.rm(sessionFile, { force: true });\n } catch (error) {\n throw new ClaudeCommandConfigError(`Failed to clear Claude session file: ${sessionFile}`, { cause: error });\n }\n }\n\n const existingSessionId = await readSessionId(sessionFile);\n if (existingSessionId) {\n return { sessionId: existingSessionId, resume: true };\n }\n\n const sessionId = randomUUID().toLowerCase();\n try {\n await fs.writeFile(sessionFile, `${sessionId}\\n`, TEXT_ENCODING);\n } catch (error) {\n throw new ClaudeCommandConfigError(`Failed to write Claude session file: ${sessionFile}`, { cause: error });\n }\n return { sessionId, resume: false };\n}\n\nasync function launchClaude(\n scope: string,\n port: number,\n clearSession: boolean,\n claudeArgs: string[],\n configFile?: string,\n): Promise<number> {\n const scopeSeedConfigPath = await resolveScopeSeedConfigPath(configFile);\n const profileStore = new ProfileStore();\n await profileStore.ensureConfig(scope, scopeSeedConfigPath);\n\n const serverManager = new HttpServerManager();\n const status = await serverManager.ensureRunning(port);\n\n if (!status.running || !status.port) {\n throw new ClaudeCommandLaunchError(status.error || 'Failed to start model proxy HTTP server');\n }\n\n const { sessionId, resume } = await resolveSessionId(scope, clearSession);\n const env = buildClaudeEnvironment(status.port, scope);\n const args = [\n ARG_SKIP_PERMISSIONS,\n ...(resume ? [ARG_RESUME, sessionId] : [ARG_SESSION_ID, sessionId]),\n ...claudeArgs,\n ];\n\n console.log(`${LOG_PREFIX} Scope: ${scope}`);\n console.log(`${LOG_PREFIX} Proxy: ${env.ANTHROPIC_BASE_URL}`);\n console.log(`${LOG_PREFIX} Session: ${sessionId}${resume ? ' (resume)' : ' (new)'}`);\n if (scopeSeedConfigPath) {\n console.log(`${LOG_PREFIX} Scope config seed: ${scopeSeedConfigPath}`);\n }\n\n return new Promise<number>((resolve, reject) => {\n const child = spawn(CLAUDE_BINARY, args, {\n stdio: STDIO_INHERIT,\n env,\n });\n\n child.on('error', (error) => {\n reject(\n new ClaudeCommandLaunchError(`Failed to launch ${CLAUDE_BINARY}`, {\n cause: error,\n }),\n );\n });\n\n child.on('exit', (code, signal) => {\n if (signal) {\n reject(new ClaudeCommandLaunchError(`${CLAUDE_BINARY} exited with signal ${signal}`));\n return;\n }\n resolve(code ?? 0);\n });\n });\n}\n\nexport const claudeCommand = new Command('claude')\n .description('Launch Claude Code through the model proxy')\n .option('-s, --scope <scope>', 'Proxy scope to use')\n .option('-p, --port <port>', 'Preferred HTTP port for the proxy', String(DEFAULT_HTTP_PORT))\n .option('-c, --config-file <path>', 'Seed a new scope from the specified scope config file')\n .option('--config <path>', 'Alias for --config-file')\n .option('--clear-session', 'Start with a fresh Claude session for the selected scope', false)\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .argument('[claudeArgs...]')\n .action(\n async (\n claudeArgs: string[],\n options: { scope?: string; port: string; clearSession: boolean; configFile?: string; config?: string },\n ) => {\n try {\n const resolvedScope = sanitizeScope(options.scope || generateScopeName());\n const port = Number.parseInt(options.port, DECIMAL_RADIX);\n if (!Number.isInteger(port) || port <= 0) {\n throw new ClaudeCommandValidationError(`Invalid port: ${options.port}`);\n }\n\n const exitCode = await launchClaude(\n resolvedScope,\n port,\n options.clearSession,\n claudeArgs,\n options.configFile ?? options.config,\n );\n process.exit(exitCode);\n } catch (error) {\n const commandError =\n error instanceof ClaudeCommandError\n ? error\n : new ClaudeCommandLaunchError('Failed to launch Claude', { cause: error });\n console.error(`${LOG_PREFIX} ${commandError.code}: ${commandError.message}`);\n console.error(`${LOG_PREFIX} ${RECOVERY_MESSAGE}`);\n if (commandError.cause) {\n console.error(`${LOG_PREFIX} Cause:`, commandError.cause);\n }\n process.exit(1);\n }\n },\n );\n","import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { PortRegistryService } from '@agimon-ai/foundation-port-registry';\nimport { type ProcessLease, createProcessLease } from '@agimon-ai/foundation-process-registry';\nimport { serve } from '@hono/node-server';\nimport { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT, DEFAULT_SERVICE_NAME, MODEL_PROXY_PORT_RANGE } from '../constants/defaults.js';\nimport { createHttpServer } from '../server/http.js';\nimport { GatewayService } from '../services/GatewayService.js';\n\nconst LOCAL_HOST = '127.0.0.1';\nconst WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'nx.json', '.git'];\nconst PORT_REGISTRY_SERVICE_TYPE = 'service' as const;\n\ntype HttpServeOptions = { port: string };\n\nfunction resolveWorkspaceRoot(startPath = process.cwd()): string {\n let current = path.resolve(startPath);\n while (true) {\n for (const marker of WORKSPACE_MARKERS) {\n if (existsSync(path.join(current, marker))) {\n return current;\n }\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return process.cwd();\n }\n current = parent;\n }\n}\n\nexport const httpServeCommand = new Command('http-serve')\n .description('Start the Claude-compatible HTTP model proxy server')\n .option('-p, --port <port>', 'Port to listen on', String(DEFAULT_HTTP_PORT))\n .action(async (options: HttpServeOptions) => {\n let processLease: ProcessLease | undefined;\n try {\n const requestedPort = Number.parseInt(options.port, 10);\n if (!Number.isInteger(requestedPort) || requestedPort <= 0) {\n throw new Error(`Invalid port: ${options.port}`);\n }\n\n const portRegistry = new PortRegistryService(process.env.PORT_REGISTRY_PATH);\n const repositoryPath = resolveWorkspaceRoot();\n const reserveResult = await portRegistry.reservePort({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n preferredPort: requestedPort,\n portRange: MODEL_PROXY_PORT_RANGE,\n pid: process.pid,\n host: LOCAL_HOST,\n force: true,\n });\n\n if (!reserveResult.success || !reserveResult.record) {\n throw new Error(reserveResult.error || `Failed to reserve port ${requestedPort}`);\n }\n\n const port = reserveResult.record.port;\n\n processLease = await createProcessLease({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid: process.pid,\n port,\n host: LOCAL_HOST,\n command: process.argv[1],\n args: process.argv.slice(2),\n });\n\n const gatewayService = new GatewayService();\n await gatewayService.ensureConfig();\n const app = createHttpServer(gatewayService);\n const server = serve({ fetch: app.fetch, port, hostname: LOCAL_HOST });\n\n console.log(`model-proxy-mcp listening on http://${LOCAL_HOST}:${port}`);\n console.log(`Claude base URL: http://${LOCAL_HOST}:${port}`);\n\n const shutdown = async (signal: string) => {\n console.log(`\\n${signal} received. Shutting down...`);\n server.close();\n await processLease?.release();\n await portRegistry.releasePort({\n repositoryPath,\n serviceName: DEFAULT_SERVICE_NAME,\n serviceType: PORT_REGISTRY_SERVICE_TYPE,\n pid: process.pid,\n });\n process.exit(0);\n };\n\n process.once('SIGINT', () => shutdown('SIGINT'));\n process.once('SIGTERM', () => shutdown('SIGTERM'));\n } catch (error) {\n await processLease?.release();\n console.error('Failed to start HTTP server:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { createServer } from '../server/index.js';\nimport { GatewayService } from '../services/GatewayService.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\nconst DEFAULT_SCOPE = 'default';\nconst MODEL_PROXY_SCOPE_ENV = 'MODEL_PROXY_MCP_SCOPE';\n\ntype McpServeOptions = { cleanup: boolean; port: string };\n\nexport const mcpServeCommand = new Command('mcp-serve')\n .description('Start MCP server with stdio transport')\n .option('--cleanup', 'Stop HTTP server on shutdown', false)\n .option('-p, --port <port>', 'Port for HTTP server', String(DEFAULT_HTTP_PORT))\n .action(async (options: McpServeOptions) => {\n try {\n const port = Number.parseInt(options.port, 10);\n if (!Number.isInteger(port) || port <= 0) {\n throw new Error(`Invalid port: ${options.port}`);\n }\n\n const gatewayService = new GatewayService();\n await gatewayService.ensureConfig(process.env[MODEL_PROXY_SCOPE_ENV] || DEFAULT_SCOPE);\n\n const manager = new HttpServerManager();\n const httpStatus = await manager.ensureRunning(port);\n if (!httpStatus.running) {\n console.error(`Warning: HTTP server failed to start: ${httpStatus.error}`);\n }\n\n let stopHealthMonitor: (() => void) | undefined;\n if (httpStatus.running) {\n stopHealthMonitor = manager.startHealthMonitor(port);\n }\n\n const handler = new StdioTransportHandler(createServer(gatewayService));\n\n const shutdown = async (signal: string) => {\n console.error(`\\nReceived ${signal}, shutting down gracefully...`);\n stopHealthMonitor?.();\n await handler.stop();\n if (options.cleanup && httpStatus.running) {\n await manager.stop();\n }\n process.exit(0);\n };\n\n process.once(\n 'SIGINT',\n () =>\n void shutdown('SIGINT').catch((error) => {\n console.error('Failed to shut down after SIGINT:', error);\n process.exit(1);\n }),\n );\n process.once(\n 'SIGTERM',\n () =>\n void shutdown('SIGTERM').catch((error) => {\n console.error('Failed to shut down after SIGTERM:', error);\n process.exit(1);\n }),\n );\n\n await handler.start();\n } catch (error) {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { DEFAULT_HTTP_PORT } from '../constants/defaults.js';\nimport { createServer } from '../server/index.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\nexport const startCommand = new Command('start')\n .description('Start HTTP and/or MCP server for the model proxy')\n .option('--mcp-only', 'Start only the MCP server', false)\n .option('--http-only', 'Start only the HTTP server', false)\n .option('-p, --port <port>', 'Port for HTTP server', String(DEFAULT_HTTP_PORT))\n .action(async (options) => {\n try {\n const httpServerManager = new HttpServerManager();\n const port = Number.parseInt(options.port, 10);\n const startHttp = !options.mcpOnly;\n const startMcp = !options.httpOnly;\n\n if (startHttp) {\n const status = await httpServerManager.ensureRunning(port);\n if (!status.running) {\n console.error(`HTTP server failed to start: ${status.error}`);\n process.exit(1);\n }\n console.log(`HTTP server running on http://127.0.0.1:${status.port}`);\n }\n\n if (startMcp) {\n const handler = new StdioTransportHandler(createServer());\n await handler.start();\n const shutdown = async (signal: string) => {\n console.error(`\\n${signal} received. Shutting down...`);\n await handler.stop();\n process.exit(0);\n };\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n } else {\n process.exit(0);\n }\n } catch (error) {\n console.error('Failed to start services:', error);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { GatewayService } from '../services/GatewayService.js';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\nimport { consoleLogger } from '../services/logger.js';\n\nconst DEFAULT_SCOPE = 'default';\nconst STATUS_COMMAND_NAME = 'status';\nconst STATUS_COMMAND_DESCRIPTION = 'Show proxy server and profile status';\nconst STATUS_ERROR_MESSAGE = 'Failed to read status';\n\nclass StatusCommandError extends Error {\n readonly code = 'STATUS_CHECK_FAILED';\n\n constructor(cause: unknown) {\n super(STATUS_ERROR_MESSAGE, { cause: cause instanceof Error ? cause : new Error(String(cause)) });\n this.name = 'StatusCommandError';\n }\n}\n\nexport const statusCommand = new Command(STATUS_COMMAND_NAME)\n .description(STATUS_COMMAND_DESCRIPTION)\n .option('-s, --scope <scope>', 'Configuration scope', DEFAULT_SCOPE)\n .action(async (options: { scope: string }) => {\n try {\n const manager = new HttpServerManager();\n const serverStatus = await manager.getStatus();\n const gateway = new GatewayService();\n const status = await gateway.getStatus(options.scope, serverStatus.port, serverStatus.pid);\n status.running = serverStatus.running;\n status.error = serverStatus.error;\n consoleLogger.info(JSON.stringify(status, null, 2));\n process.exit(0);\n } catch (error) {\n const statusError = new StatusCommandError(error);\n consoleLogger.error(STATUS_ERROR_MESSAGE, {\n command: STATUS_COMMAND_NAME,\n code: statusError.code,\n scope: options.scope,\n cause: statusError.cause,\n });\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport { HttpServerManager } from '../services/HttpServerManager.js';\n\nexport const stopCommand = new Command('stop').description('Stop the background HTTP server').action(async () => {\n try {\n const manager = new HttpServerManager();\n const stopped = await manager.stop();\n console.log(stopped ? 'HTTP server stopped' : 'No HTTP server running');\n process.exit(0);\n } catch (error) {\n console.error('Failed to stop HTTP server:', error);\n process.exit(1);\n }\n});\n","#!/usr/bin/env node\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport { claudeCommand } from './commands/claude.js';\nimport { httpServeCommand } from './commands/http-serve.js';\nimport { mcpServeCommand } from './commands/mcp-serve.js';\nimport { startCommand } from './commands/start.js';\nimport { statusCommand } from './commands/status.js';\nimport { stopCommand } from './commands/stop.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nasync function main() {\n const program = new Command();\n program.name('model-proxy-mcp').description('Claude-compatible model proxy MCP').version(packageJson.version);\n program.addCommand(startCommand);\n program.addCommand(stopCommand);\n program.addCommand(statusCommand);\n program.addCommand(claudeCommand);\n program.addCommand(httpServeCommand);\n program.addCommand(mcpServeCommand);\n await program.parseAsync(process.argv);\n}\n\nmain();\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=require(`./stdio-CffHO4FT.cjs`);exports.ConversationHistoryService=e.a,exports.GatewayService=e.i,exports.ProfileStore=e.o,exports.StdioTransportHandler=e.t,exports.createHttpServer=e.r,exports.createServer=e.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./stdio-n9VKykAQ.cjs`);exports.ConversationHistoryService=e.o,exports.GatewayService=e.i,exports.ProfileStore=e.a,exports.StdioTransportHandler=e.t,exports.createHttpServer=e.r,exports.createServer=e.n;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,i as t,n,o as r,r as i,t as a}from"./stdio-P-s6QuNu.mjs";export{e as ConversationHistoryService,t as GatewayService,r as ProfileStore,a as StdioTransportHandler,i as createHttpServer,n as createServer};
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./stdio-Bnkr5Z4C.mjs";export{r as ConversationHistoryService,t as GatewayService,e as ProfileStore,a as StdioTransportHandler,i as createHttpServer,n as createServer};