@cognisos/liminal 2.2.2 → 2.4.0
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/bin.js +1384 -235
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/commands/init.ts","../src/config/loader.ts","../src/config/paths.ts","../src/config/schema.ts","../src/ui/prompts.ts","../src/commands/login.ts","../src/auth/supabase.ts","../src/commands/logout.ts","../src/rsc/pipeline.ts","../src/proxy/completions.ts","../src/rsc/message-compressor.ts","../src/rsc/learning.ts","../src/proxy/streaming.ts","../src/proxy/messages.ts","../src/proxy/anthropic-streaming.ts","../src/proxy/handler.ts","../src/proxy/server.ts","../src/daemon/logger.ts","../src/daemon/lifecycle.ts","../src/commands/start.ts","../src/commands/stop.ts","../src/commands/status.ts","../src/commands/summary.ts","../src/commands/config.ts","../src/commands/logs.ts","../src/bin.ts"],"sourcesContent":["declare const __VERSION__: string\nexport const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.2.1'\n\n// FIGlet-style \"LIMINAL\" banner\nconst BANNER_LINES = [\n ' ___ ___ _____ ______ ___ ________ ________ ___',\n '|\\\\ \\\\ |\\\\ \\\\|\\\\ _ \\\\ _ \\\\|\\\\ \\\\|\\\\ ___ \\\\|\\\\ __ \\\\|\\\\ \\\\',\n '\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\\\\\__\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ \\\\|\\\\ \\\\ \\\\ \\\\',\n ' \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\|__| \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ __ \\\\ \\\\ \\\\',\n ' \\\\ \\\\ \\\\____\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\____',\n ' \\\\ \\\\_______\\\\ \\\\__\\\\ \\\\__\\\\ \\\\ \\\\__\\\\ \\\\__\\\\ \\\\__\\\\\\\\ \\\\__\\\\ \\\\__\\\\ \\\\__\\\\ \\\\_______\\\\',\n ' \\\\|_______|\\\\|__|\\\\|__| \\\\|__|\\\\|__|\\\\|__| \\\\|__|\\\\|__|\\\\|__|\\\\|_______|',\n]\n\nexport function printBanner(): void {\n console.log()\n for (const line of BANNER_LINES) {\n console.log(line)\n }\n console.log()\n console.log(` v${VERSION} -- brought to you by Cognisos`)\n console.log()\n}\n","import { createInterface } from 'node:readline/promises'\nimport { stdin, stdout } from 'node:process'\nimport { existsSync, readFileSync, appendFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { saveConfig, ensureDirectories } from '../config/loader.js'\nimport { DEFAULTS } from '../config/schema.js'\nimport { CONFIG_FILE } from '../config/paths.js'\nimport { printBanner } from '../version.js'\nimport { multiSelectPrompt, selectPrompt } from '../ui/prompts.js'\nimport { runAuthFlow } from './login.js'\nimport type { Tool } from '../types.js'\n\n// ─── Shell profile detection ─────────────────────────────────────────\n\ninterface ShellProfile {\n name: string\n path: string\n}\n\nfunction detectShellProfile(): ShellProfile | null {\n const shell = process.env.SHELL || ''\n const home = homedir()\n\n // Prefer the user's actual shell\n if (shell.endsWith('/zsh')) {\n const zshrc = join(home, '.zshrc')\n return { name: '~/.zshrc', path: zshrc }\n }\n\n if (shell.endsWith('/bash')) {\n // macOS uses .bash_profile, Linux uses .bashrc\n const bashProfile = join(home, '.bash_profile')\n if (existsSync(bashProfile)) {\n return { name: '~/.bash_profile', path: bashProfile }\n }\n return { name: '~/.bashrc', path: join(home, '.bashrc') }\n }\n\n // Fallback: check common files\n const candidates: ShellProfile[] = [\n { name: '~/.zshrc', path: join(home, '.zshrc') },\n { name: '~/.bashrc', path: join(home, '.bashrc') },\n { name: '~/.profile', path: join(home, '.profile') },\n ]\n\n for (const c of candidates) {\n if (existsSync(c.path)) return c\n }\n\n return null\n}\n\n/**\n * Build the export lines needed for the selected tools.\n */\nfunction getExportLines(tools: Tool[], port: number): string[] {\n const base = `http://127.0.0.1:${port}`\n const lines: string[] = []\n\n if (tools.includes('claude-code')) {\n lines.push(`export ANTHROPIC_BASE_URL=${base}`)\n }\n if (tools.includes('codex') || tools.includes('openai-compatible')) {\n lines.push(`export OPENAI_BASE_URL=${base}/v1`)\n }\n\n return lines\n}\n\n/**\n * Check if a line already exists in a file (avoids duplicate entries).\n */\nfunction lineExistsInFile(filePath: string, line: string): boolean {\n if (!existsSync(filePath)) return false\n try {\n const content = readFileSync(filePath, 'utf-8')\n return content.includes(line)\n } catch {\n return false\n }\n}\n\n/**\n * Append export lines to shell profile, with a Liminal comment header.\n */\nfunction appendToShellProfile(profile: ShellProfile, lines: string[]): void {\n const block = [\n '',\n '# Liminal — route AI tools through compression proxy',\n ...lines,\n ].join('\\n') + '\\n'\n\n appendFileSync(profile.path, block, 'utf-8')\n}\n\nexport async function initCommand(): Promise<void> {\n printBanner()\n console.log(' Welcome to Liminal -- Your Transparency & Context Partner')\n console.log()\n console.log(\" Let's start evolving.\")\n console.log()\n\n // ── Authenticate ──────────────────────────────────────────────\n const apiKey = await runAuthFlow()\n console.log()\n\n // ── Port selection (readline) ─────────────────────────────────\n const rl = createInterface({ input: stdin, output: stdout })\n let port: number\n\n try {\n const portInput = await rl.question(` Proxy port [${DEFAULTS.port}]: `)\n port = portInput.trim() ? parseInt(portInput.trim(), 10) : DEFAULTS.port\n if (isNaN(port) || port < 1 || port > 65535) {\n console.error('\\n Error: Invalid port number.')\n process.exit(1)\n }\n } finally {\n rl.close()\n }\n\n console.log()\n\n // ── Interactive prompts (raw mode) ──────────────────────────────\n const toolsResult = await multiSelectPrompt<Tool>({\n message: 'Which AI tools will you use with Liminal?',\n options: [\n { label: 'Claude Code', value: 'claude-code', default: true },\n { label: 'Codex', value: 'codex' },\n { label: 'Cursor', value: 'cursor' },\n { label: 'Other / OpenAI', value: 'openai-compatible' },\n ],\n })\n const tools: Tool[] = toolsResult ?? ['claude-code']\n\n console.log()\n\n const learnResult = await selectPrompt<boolean>({\n message: 'Learn from LLM responses?',\n options: [\n { label: 'Yes', value: true, description: 'Improve compression over time' },\n { label: 'No', value: false, description: 'Skip response learning' },\n ],\n defaultIndex: 0,\n })\n const learnFromResponses = learnResult ?? true\n\n console.log()\n\n // ── Save config ─────────────────────────────────────────────────\n const apiBaseUrl = DEFAULTS.apiBaseUrl\n ensureDirectories()\n saveConfig({\n apiKey,\n apiBaseUrl,\n upstreamBaseUrl: DEFAULTS.upstreamBaseUrl,\n anthropicUpstreamUrl: DEFAULTS.anthropicUpstreamUrl,\n port,\n learnFromResponses,\n tools,\n compressionThreshold: DEFAULTS.compressionThreshold,\n compressRoles: DEFAULTS.compressRoles,\n latencyBudgetMs: DEFAULTS.latencyBudgetMs,\n enabled: DEFAULTS.enabled,\n })\n\n console.log()\n console.log(` Configuration saved to ${CONFIG_FILE}`)\n console.log()\n\n // ── Shell auto-configuration ────────────────────────────────────\n const exportLines = getExportLines(tools, port)\n const hasCursor = tools.includes('cursor')\n\n if (exportLines.length > 0) {\n const profile = detectShellProfile()\n\n if (profile) {\n // Check if already configured\n const allExist = exportLines.every((line) => lineExistsInFile(profile.path, line))\n\n if (allExist) {\n console.log(` Shell already configured in ${profile.name}`)\n } else {\n const autoResult = await selectPrompt<boolean>({\n message: 'Configure shell automatically?',\n options: [\n { label: 'Yes', value: true, description: `Add to ${profile.name}` },\n { label: 'No', value: false, description: \"I'll set it up manually\" },\n ],\n defaultIndex: 0,\n })\n\n if (autoResult === true) {\n // Only append lines that don't already exist\n const newLines = exportLines.filter((line) => !lineExistsInFile(profile.path, line))\n if (newLines.length > 0) {\n appendToShellProfile(profile, newLines)\n }\n console.log()\n console.log(` Added to ${profile.name}:`)\n for (const line of exportLines) {\n console.log(` ${line}`)\n }\n console.log()\n console.log(` Run \\x1b[1msource ${profile.name}\\x1b[0m or restart your terminal to apply.`)\n } else {\n console.log()\n console.log(' Add these to your shell profile:')\n console.log()\n for (const line of exportLines) {\n console.log(` ${line}`)\n }\n }\n }\n } else {\n // No shell profile detected — show manual instructions\n console.log(' Add these to your shell profile:')\n console.log()\n for (const line of exportLines) {\n console.log(` ${line}`)\n }\n }\n }\n\n // Cursor requires manual GUI configuration\n if (hasCursor) {\n console.log()\n console.log(' Cursor setup (manual):')\n console.log(` Settings > Models > OpenAI API Base URL: http://127.0.0.1:${port}/v1`)\n }\n\n console.log()\n console.log(' Next step:')\n console.log(' liminal start')\n console.log()\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { LIMINAL_DIR, CONFIG_FILE, LOG_DIR } from './paths.js'\nimport { DEFAULTS } from './schema.js'\nimport type { RSCConfig } from './schema.js'\n\n/**\n * Load config from ~/.liminal/config.json, merged with defaults and env var overrides.\n * Priority: env vars > config file > defaults\n */\nexport function loadConfig(): RSCConfig {\n let fileConfig: Partial<RSCConfig> = {}\n\n if (existsSync(CONFIG_FILE)) {\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8')\n fileConfig = JSON.parse(raw)\n } catch {\n // Corrupted config file — fall through to defaults\n }\n }\n\n const merged: RSCConfig = {\n apiKey: fileConfig.apiKey ?? '',\n apiBaseUrl: DEFAULTS.apiBaseUrl,\n upstreamBaseUrl: DEFAULTS.upstreamBaseUrl,\n anthropicUpstreamUrl: DEFAULTS.anthropicUpstreamUrl,\n port: DEFAULTS.port,\n compressionThreshold: DEFAULTS.compressionThreshold,\n compressRoles: DEFAULTS.compressRoles,\n learnFromResponses: DEFAULTS.learnFromResponses,\n latencyBudgetMs: DEFAULTS.latencyBudgetMs,\n enabled: DEFAULTS.enabled,\n tools: DEFAULTS.tools,\n ...fileConfig,\n }\n\n // Environment variable overrides\n if (process.env.LIMINAL_API_KEY) merged.apiKey = process.env.LIMINAL_API_KEY\n if (process.env.LIMINAL_API_URL) merged.apiBaseUrl = process.env.LIMINAL_API_URL\n if (process.env.LIMINAL_UPSTREAM_URL) merged.upstreamBaseUrl = process.env.LIMINAL_UPSTREAM_URL\n if (process.env.LIMINAL_ANTHROPIC_URL) merged.anthropicUpstreamUrl = process.env.LIMINAL_ANTHROPIC_URL\n if (process.env.LIMINAL_PORT) merged.port = parseInt(process.env.LIMINAL_PORT, 10)\n\n return merged\n}\n\n/**\n * Apply CLI flag overrides on top of loaded config.\n */\nexport function applyOverrides(\n config: RSCConfig,\n overrides: Partial<Pick<RSCConfig, 'port' | 'upstreamBaseUrl'>>,\n): RSCConfig {\n return { ...config, ...overrides }\n}\n\n/**\n * Save config to ~/.liminal/config.json. Creates ~/.liminal/ and ~/.liminal/logs/ if needed.\n */\nexport function saveConfig(config: Partial<RSCConfig>): void {\n ensureDirectories()\n\n let existing: Partial<RSCConfig> = {}\n if (existsSync(CONFIG_FILE)) {\n try {\n existing = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'))\n } catch {\n // Overwrite corrupted file\n }\n }\n\n const merged = { ...existing, ...config }\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + '\\n', 'utf-8')\n}\n\n/**\n * Ensure ~/.liminal/ and ~/.liminal/logs/ directories exist.\n */\nexport function ensureDirectories(): void {\n if (!existsSync(LIMINAL_DIR)) mkdirSync(LIMINAL_DIR, { recursive: true })\n if (!existsSync(LOG_DIR)) mkdirSync(LOG_DIR, { recursive: true })\n // Ensure parent of config file exists\n const configDir = dirname(CONFIG_FILE)\n if (!existsSync(configDir)) mkdirSync(configDir, { recursive: true })\n}\n\n/**\n * Check if a valid config file exists with an API key.\n */\nexport function isConfigured(): boolean {\n try {\n const config = loadConfig()\n return config.apiKey.length > 0\n } catch {\n return false\n }\n}\n\n/**\n * Mask an API key for display: show first 8 chars + last 4.\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 12) return '****'\n return key.slice(0, 8) + '...' + key.slice(-4)\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport const LIMINAL_DIR = join(homedir(), '.liminal')\nexport const CONFIG_FILE = join(LIMINAL_DIR, 'config.json')\nexport const PID_FILE = join(LIMINAL_DIR, 'liminal.pid')\nexport const LOG_DIR = join(LIMINAL_DIR, 'logs')\nexport const LOG_FILE = join(LOG_DIR, 'liminal.log')\n","export interface RSCConfig {\n apiKey: string\n apiBaseUrl: string\n upstreamBaseUrl: string\n anthropicUpstreamUrl: string\n port: number\n compressionThreshold: number\n compressRoles: string[]\n learnFromResponses: boolean\n latencyBudgetMs: number\n enabled: boolean\n tools: string[]\n}\n\nexport const DEFAULTS: Omit<RSCConfig, 'apiKey'> = {\n apiBaseUrl: 'https://rsc-platform-production.up.railway.app',\n upstreamBaseUrl: 'https://api.openai.com',\n anthropicUpstreamUrl: 'https://api.anthropic.com',\n port: 3141,\n compressionThreshold: 100,\n compressRoles: ['user'],\n learnFromResponses: true,\n latencyBudgetMs: 0,\n enabled: true,\n tools: [],\n}\n\n/** Keys that can be set via `liminal config --set` */\nexport const CONFIGURABLE_KEYS = new Set<string>([\n 'apiBaseUrl',\n 'upstreamBaseUrl',\n 'anthropicUpstreamUrl',\n 'port',\n 'compressionThreshold',\n 'compressRoles',\n 'learnFromResponses',\n 'latencyBudgetMs',\n 'enabled',\n 'tools',\n])\n","/**\n * Lightweight interactive terminal prompts — zero external dependencies.\n * Uses raw stdin mode for arrow-key navigation.\n */\n\n// ─── ANSI escape sequences ───────────────────────────────────────────\n\nconst ANSI = {\n HIDE_CURSOR: '\\x1b[?25l',\n SHOW_CURSOR: '\\x1b[?25h',\n CLEAR_LINE: '\\x1b[2K',\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m',\n CYAN: '\\x1b[36m',\n RESET: '\\x1b[0m',\n moveUp: (n: number) => (n > 0 ? `\\x1b[${n}A` : ''),\n} as const\n\n// ─── Key parsing ─────────────────────────────────────────────────────\n\nexport type KeyPress =\n | { type: 'up' }\n | { type: 'down' }\n | { type: 'enter' }\n | { type: 'space' }\n | { type: 'escape' }\n | { type: 'ctrlc' }\n | { type: 'backspace' }\n | { type: 'char'; char: string }\n | { type: 'other' }\n\nexport function parseKey(data: Buffer): KeyPress {\n if (data.length === 0) return { type: 'other' }\n\n // Ctrl+C\n if (data[0] === 0x03) return { type: 'ctrlc' }\n\n // Arrow keys: ESC [ A/B\n if (data.length >= 3 && data[0] === 0x1b && data[1] === 0x5b) {\n if (data[2] === 0x41) return { type: 'up' }\n if (data[2] === 0x42) return { type: 'down' }\n return { type: 'other' }\n }\n\n // Standalone Escape\n if (data.length === 1 && data[0] === 0x1b) return { type: 'escape' }\n\n // Enter\n if (data[0] === 0x0d || data[0] === 0x0a) return { type: 'enter' }\n\n // Space\n if (data[0] === 0x20) return { type: 'space' }\n\n // Backspace (DEL on macOS)\n if (data[0] === 0x7f || data[0] === 0x08) return { type: 'backspace' }\n\n // Printable ASCII characters (0x21-0x7e)\n if (data.length === 1 && data[0] >= 0x21 && data[0] <= 0x7e) {\n return { type: 'char', char: String.fromCharCode(data[0]) }\n }\n\n return { type: 'other' }\n}\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface SelectOption<T> {\n label: string\n value: T\n description?: string\n}\n\nexport interface MultiSelectOption<T> extends SelectOption<T> {\n default?: boolean\n}\n\ninterface Streams {\n stdin: NodeJS.ReadableStream & { setRawMode?: (mode: boolean) => void; isTTY?: boolean }\n stdout: { write: (s: string) => boolean }\n}\n\ninterface SelectConfig<T> {\n message: string\n options: SelectOption<T>[]\n defaultIndex?: number\n _streams?: Streams\n}\n\ninterface MultiSelectConfig<T> {\n message: string\n options: MultiSelectOption<T>[]\n _streams?: Streams\n}\n\n// ─── Render helpers ──────────────────────────────────────────────────\n\nexport interface RenderResult {\n text: string\n lineCount: number\n}\n\nexport function renderSelect<T>(\n options: SelectOption<T>[],\n cursorIndex: number,\n message: string,\n): RenderResult {\n const lines: string[] = []\n lines.push(` ${ANSI.BOLD}${message}${ANSI.RESET}`)\n lines.push('')\n\n const maxLabel = Math.max(...options.map((o) => o.label.length))\n\n for (let i = 0; i < options.length; i++) {\n const focused = i === cursorIndex\n const pointer = focused ? `${ANSI.CYAN}->${ANSI.RESET}` : ' '\n const label = focused\n ? `${ANSI.BOLD}${options[i].label.padEnd(maxLabel)}${ANSI.RESET}`\n : `${options[i].label.padEnd(maxLabel)}`\n const desc = options[i].description\n ? ` ${ANSI.DIM}${options[i].description}${ANSI.RESET}`\n : ''\n lines.push(` ${pointer} ${label}${desc}`)\n }\n\n lines.push('')\n return { text: lines.join('\\n'), lineCount: lines.length }\n}\n\nexport function renderMultiSelect<T>(\n options: MultiSelectOption<T>[],\n cursorIndex: number,\n selected: Set<number>,\n message: string,\n): RenderResult {\n const lines: string[] = []\n lines.push(` ${ANSI.BOLD}${message}${ANSI.RESET}`)\n lines.push('')\n\n const maxLabel = Math.max(...options.map((o) => o.label.length))\n\n for (let i = 0; i < options.length; i++) {\n const focused = i === cursorIndex\n const checked = selected.has(i)\n const pointer = focused ? `${ANSI.CYAN}->${ANSI.RESET}` : ' '\n const box = checked\n ? `${ANSI.CYAN}[x]${ANSI.RESET}`\n : `${ANSI.DIM}[ ]${ANSI.RESET}`\n const label = focused\n ? `${ANSI.BOLD}${options[i].label.padEnd(maxLabel)}${ANSI.RESET}`\n : `${options[i].label.padEnd(maxLabel)}`\n const desc = options[i].description\n ? ` ${ANSI.DIM}${options[i].description}${ANSI.RESET}`\n : ''\n lines.push(` ${pointer} ${box} ${label}${desc}`)\n }\n\n lines.push('')\n lines.push(` ${ANSI.DIM}Space to toggle, Enter to confirm${ANSI.RESET}`)\n lines.push('')\n return { text: lines.join('\\n'), lineCount: lines.length }\n}\n\n// ─── Raw mode lifecycle ──────────────────────────────────────────────\n\nfunction withRawMode<T>(\n streams: Streams,\n handler: (\n resolve: (value: T) => void,\n ) => (key: KeyPress) => void,\n): Promise<T> {\n const { stdin, stdout } = streams\n\n return new Promise<T>((resolve, reject) => {\n let cleaned = false\n\n function cleanup() {\n if (cleaned) return\n cleaned = true\n stdin.removeListener('data', onData)\n if (stdin.setRawMode) stdin.setRawMode(false)\n if ('pause' in stdin && typeof (stdin as any).pause === 'function') {\n (stdin as any).pause()\n }\n stdout.write(ANSI.SHOW_CURSOR)\n process.removeListener('exit', cleanup)\n }\n\n function onData(data: Buffer) {\n const key = parseKey(data)\n if (key.type === 'ctrlc') {\n cleanup()\n process.exit(130)\n }\n keyHandler(key)\n }\n\n const keyHandler = handler((value: T) => {\n cleanup()\n resolve(value)\n })\n\n // Safety: restore terminal on unexpected exit\n process.on('exit', cleanup)\n\n try {\n if (stdin.setRawMode) stdin.setRawMode(true)\n stdout.write(ANSI.HIDE_CURSOR)\n stdin.on('data', onData)\n if ('resume' in stdin && typeof (stdin as any).resume === 'function') {\n (stdin as any).resume()\n }\n } catch (err) {\n cleanup()\n reject(err)\n }\n })\n}\n\n// ─── Public API ──────────────────────────────────────────────────────\n\nexport async function selectPrompt<T>(config: SelectConfig<T>): Promise<T | null> {\n const { message, options, defaultIndex = 0, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let cursorIndex = defaultIndex\n let prevLineCount = 0\n\n function draw() {\n const { text, lineCount } = renderSelect(options, cursorIndex, message)\n // Move up to overwrite previous render\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n // Clear and write each line\n const lines = text.split('\\n')\n for (const line of lines) {\n streams.stdout.write(ANSI.CLEAR_LINE + line + '\\n')\n }\n prevLineCount = lineCount\n }\n\n draw()\n\n const result = await withRawMode<T | null>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'up':\n cursorIndex = (cursorIndex - 1 + options.length) % options.length\n draw()\n break\n case 'down':\n cursorIndex = (cursorIndex + 1) % options.length\n draw()\n break\n case 'enter':\n resolve(options[cursorIndex].value)\n break\n case 'escape':\n resolve(null)\n break\n }\n }\n })\n\n // Show confirmed selection\n if (result !== null) {\n const selected = options.find((o) => o.value === result)\n if (selected) {\n // Overwrite prompt with confirmed value\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n for (let i = 0; i < prevLineCount; i++) {\n streams.stdout.write(ANSI.CLEAR_LINE + '\\n')\n }\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET} ${ANSI.CYAN}${selected.label}${ANSI.RESET}\\n`)\n }\n }\n\n return result\n}\n\nexport async function multiSelectPrompt<T>(config: MultiSelectConfig<T>): Promise<T[] | null> {\n const { message, options, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let cursorIndex = 0\n const selected = new Set<number>()\n let prevLineCount = 0\n\n // Pre-fill defaults\n for (let i = 0; i < options.length; i++) {\n if (options[i].default) selected.add(i)\n }\n\n function draw() {\n const { text, lineCount } = renderMultiSelect(options, cursorIndex, selected, message)\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n const lines = text.split('\\n')\n for (const line of lines) {\n streams.stdout.write(ANSI.CLEAR_LINE + line + '\\n')\n }\n prevLineCount = lineCount\n }\n\n draw()\n\n const result = await withRawMode<T[] | null>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'up':\n cursorIndex = (cursorIndex - 1 + options.length) % options.length\n draw()\n break\n case 'down':\n cursorIndex = (cursorIndex + 1) % options.length\n draw()\n break\n case 'space':\n if (selected.has(cursorIndex)) {\n selected.delete(cursorIndex)\n } else {\n selected.add(cursorIndex)\n }\n draw()\n break\n case 'enter':\n if (selected.size > 0) {\n const values = [...selected].sort().map((i) => options[i].value)\n resolve(values)\n }\n // If nothing selected, ignore Enter (must select at least 1)\n break\n case 'escape':\n resolve(null)\n break\n }\n }\n })\n\n // Show confirmed selection\n if (result !== null) {\n const labels = [...selected].sort().map((i) => options[i].label)\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n for (let i = 0; i < prevLineCount; i++) {\n streams.stdout.write(ANSI.CLEAR_LINE + '\\n')\n }\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET} ${ANSI.CYAN}${labels.join(', ')}${ANSI.RESET}\\n`)\n }\n\n return result\n}\n\n// ─── Password prompt ─────────────────────────────────────────────────\n\ninterface PasswordConfig {\n message: string\n _streams?: Streams\n}\n\nexport async function passwordPrompt(config: PasswordConfig): Promise<string> {\n const { message, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let password = ''\n\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET}: `)\n\n const result = await withRawMode<string>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'char':\n password += (key as { type: 'char'; char: string }).char\n streams.stdout.write('*')\n break\n case 'space':\n password += ' '\n streams.stdout.write('*')\n break\n case 'backspace':\n if (password.length > 0) {\n password = password.slice(0, -1)\n streams.stdout.write('\\b \\b')\n }\n break\n case 'enter':\n streams.stdout.write('\\n')\n resolve(password)\n break\n case 'escape':\n streams.stdout.write('\\n')\n resolve('')\n break\n }\n }\n })\n\n return result\n}\n","import { createInterface } from 'node:readline/promises'\nimport { stdin, stdout } from 'node:process'\nimport { signIn, signUp, authenticateAndGetKey } from '../auth/supabase.js'\nimport { saveConfig, ensureDirectories, loadConfig } from '../config/loader.js'\nimport { DEFAULTS } from '../config/schema.js'\nimport { printBanner } from '../version.js'\nimport { selectPrompt, passwordPrompt } from '../ui/prompts.js'\nimport type { AuthError } from '../auth/supabase.js'\n\nexport async function loginCommand(): Promise<void> {\n printBanner()\n\n // Check if already logged in\n try {\n const config = loadConfig()\n if (config.apiKey && config.apiKey.startsWith('fmcp_')) {\n console.log(' Already logged in.')\n console.log(' Run \\x1b[1mliminal logout\\x1b[0m first to switch accounts.')\n return\n }\n } catch {\n // No config yet — proceed with login\n }\n\n await runAuthFlow()\n}\n\n/**\n * Shared auth flow used by both `liminal login` and `liminal init`.\n * Returns the API key on success.\n */\nexport async function runAuthFlow(): Promise<string> {\n const modeResult = await selectPrompt<'login' | 'signup'>({\n message: 'Welcome to Liminal',\n options: [\n { label: 'Log in', value: 'login', description: 'I have an account' },\n { label: 'Create account', value: 'signup', description: 'New to Liminal' },\n ],\n defaultIndex: 0,\n })\n const mode = modeResult ?? 'login'\n\n console.log()\n\n // Collect credentials\n const rl = createInterface({ input: stdin, output: stdout })\n let name = ''\n let email: string\n\n try {\n if (mode === 'signup') {\n name = (await rl.question(' \\x1b[1mName\\x1b[0m: ')).trim()\n if (!name) {\n console.error('\\n Error: Name is required.')\n process.exit(1)\n }\n }\n\n email = (await rl.question(' \\x1b[1mEmail\\x1b[0m: ')).trim()\n if (!email) {\n console.error('\\n Error: Email is required.')\n process.exit(1)\n }\n } finally {\n rl.close()\n }\n\n // Password (masked)\n const password = await passwordPrompt({ message: 'Password' })\n if (!password) {\n console.error('\\n Error: Password is required.')\n process.exit(1)\n }\n\n console.log()\n\n // Authenticate\n const action = mode === 'signup' ? 'Creating account' : 'Logging in'\n process.stdout.write(` ${action}... `)\n\n try {\n const auth = mode === 'signup'\n ? await signUp(email, password, name)\n : await signIn(email, password)\n\n console.log('OK')\n\n // Fetch or create API key\n process.stdout.write(' Setting up API key... ')\n const apiKey = await authenticateAndGetKey(auth)\n console.log('OK')\n\n // Save to config\n ensureDirectories()\n saveConfig({\n apiKey,\n apiBaseUrl: DEFAULTS.apiBaseUrl,\n })\n\n console.log()\n console.log(` Logged in as \\x1b[1m${auth.email}\\x1b[0m`)\n\n return apiKey\n } catch (err) {\n console.log('FAILED')\n const authErr = err as AuthError\n console.error(`\\n ${authErr.message}`)\n\n if (mode === 'login' && authErr.message?.includes('Invalid login')) {\n console.error(' Check your email and password, then try again.')\n }\n\n process.exit(1)\n }\n}\n","/**\n * Lightweight Supabase Auth client using fetch — zero npm dependencies.\n * Uses the public anon key (same as web frontend).\n */\nimport { randomBytes } from 'node:crypto'\n\nconst SUPABASE_URL = 'https://nzcneiyymvgxvttbenhp.supabase.co'\nconst SUPABASE_ANON_KEY =\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im56Y25laXl5bXZneHZ0dGJlbmhwIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQwNjQ0MjcsImV4cCI6MjA2OTY0MDQyN30.x3E-zGRadbPMmxRqT_PB_KOi00htKpgeb8GiQa4g2z0'\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface AuthResult {\n accessToken: string\n userId: string\n email: string\n}\n\nexport interface AuthError {\n message: string\n status?: number\n}\n\n// ─── Auth ────────────────────────────────────────────────────────────\n\nfunction supabaseHeaders(accessToken?: string): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_ANON_KEY,\n }\n if (accessToken) {\n headers['Authorization'] = `Bearer ${accessToken}`\n }\n return headers\n}\n\n/**\n * Sign in with email and password.\n */\nexport async function signIn(email: string, password: string): Promise<AuthResult> {\n const res = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=password`, {\n method: 'POST',\n headers: supabaseHeaders(),\n body: JSON.stringify({ email, password }),\n })\n\n const body = (await res.json()) as Record<string, any>\n\n if (!res.ok) {\n const msg = body?.error_description || body?.error || body?.msg || 'Authentication failed'\n const err: AuthError = { message: msg, status: res.status }\n throw err\n }\n\n return {\n accessToken: body.access_token,\n userId: body.user?.id,\n email: body.user?.email ?? email,\n }\n}\n\n/**\n * Sign up with email, password, and name.\n */\nexport async function signUp(\n email: string,\n password: string,\n name: string,\n): Promise<AuthResult> {\n const res = await fetch(`${SUPABASE_URL}/auth/v1/signup`, {\n method: 'POST',\n headers: supabaseHeaders(),\n body: JSON.stringify({\n email,\n password,\n data: { name },\n }),\n })\n\n const body = (await res.json()) as Record<string, any>\n\n if (!res.ok) {\n const msg = body?.error_description || body?.error || body?.msg || 'Sign up failed'\n const err: AuthError = { message: msg, status: res.status }\n throw err\n }\n\n // Supabase may return identities: [] if email confirmation is required\n if (body.user?.identities?.length === 0) {\n const err: AuthError = { message: 'Account already exists. Try logging in instead.' }\n throw err\n }\n\n return {\n accessToken: body.access_token,\n userId: body.user?.id,\n email: body.user?.email ?? email,\n }\n}\n\n// ─── API Key Management ──────────────────────────────────────────────\n\n/**\n * Fetch existing active API key for the authenticated user.\n */\nexport async function fetchApiKey(accessToken: string, userId: string): Promise<string | null> {\n const params = new URLSearchParams({\n user_id: `eq.${userId}`,\n is_active: 'eq.true',\n select: 'api_key',\n limit: '1',\n })\n\n const res = await fetch(`${SUPABASE_URL}/rest/v1/user_api_keys?${params}`, {\n headers: supabaseHeaders(accessToken),\n })\n\n if (!res.ok) return null\n\n const rows = await res.json()\n if (Array.isArray(rows) && rows.length > 0 && rows[0].api_key) {\n return rows[0].api_key as string\n }\n\n return null\n}\n\n/**\n * Generate and insert a new API key for the authenticated user.\n */\nexport async function createApiKey(accessToken: string, userId: string): Promise<string> {\n const apiKey = `fmcp_${randomBytes(32).toString('hex')}`\n\n const res = await fetch(`${SUPABASE_URL}/rest/v1/user_api_keys`, {\n method: 'POST',\n headers: {\n ...supabaseHeaders(accessToken),\n 'Prefer': 'return=representation',\n },\n body: JSON.stringify({\n user_id: userId,\n key_name: 'Liminal CLI',\n api_key: apiKey,\n is_active: true,\n }),\n })\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, any>\n const msg = body?.message || body?.error || 'Failed to create API key'\n throw { message: msg, status: res.status } as AuthError\n }\n\n return apiKey\n}\n\n/**\n * Full login flow: authenticate then fetch or create API key.\n */\nexport async function authenticateAndGetKey(\n auth: AuthResult,\n): Promise<string> {\n // Try to fetch existing key first\n const existingKey = await fetchApiKey(auth.accessToken, auth.userId)\n if (existingKey) return existingKey\n\n // No key found — create one\n return createApiKey(auth.accessToken, auth.userId)\n}\n","import { saveConfig, isConfigured } from '../config/loader.js'\n\nexport async function logoutCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log(' Not currently logged in.')\n return\n }\n\n saveConfig({ apiKey: '' })\n console.log(' Logged out.')\n console.log(' Run \\x1b[1mliminal login\\x1b[0m to reconnect.')\n}\n","import {\n CompressionPipeline,\n RSCTransport,\n RSCEventEmitter,\n Session,\n CircuitBreaker,\n} from '@cognisos/rsc-sdk'\nimport type { SessionSummary, CircuitState } from '@cognisos/rsc-sdk'\n\nexport interface PipelineConfig {\n rscApiKey: string\n rscBaseUrl: string\n compressionThreshold: number\n learnFromResponses: boolean\n latencyBudgetMs?: number\n sessionId?: string\n}\n\nexport class RSCPipelineWrapper {\n readonly pipeline: CompressionPipeline\n readonly session: Session\n readonly events: RSCEventEmitter\n readonly transport: RSCTransport\n private readonly circuitBreaker: CircuitBreaker\n\n constructor(config: PipelineConfig) {\n this.circuitBreaker = new CircuitBreaker(5, 5 * 60 * 1000)\n\n this.transport = new RSCTransport({\n baseUrl: config.rscBaseUrl,\n apiKey: config.rscApiKey,\n timeout: 30_000,\n maxRetries: 3,\n circuitBreaker: this.circuitBreaker,\n })\n\n this.events = new RSCEventEmitter()\n this.session = new Session(config.sessionId)\n\n this.pipeline = new CompressionPipeline(\n this.transport,\n {\n threshold: config.compressionThreshold,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs,\n sessionId: this.session.sessionId,\n },\n this.events,\n )\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n await this.transport.get<{ status: string }>('/health')\n return true\n } catch {\n return false\n }\n }\n\n getSessionSummary(): SessionSummary {\n return this.session.getSummary()\n }\n\n getCircuitState(): CircuitState {\n return this.circuitBreaker.getState()\n }\n\n isCircuitOpen(): boolean {\n return this.circuitBreaker.getState() === 'open'\n }\n\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset()\n }\n}\n","import * as http from 'node:http'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport { compressMessages } from '../rsc/message-compressor.js'\nimport { createStreamLearningBuffer } from '../rsc/learning.js'\nimport { pipeSSEResponse } from './streaming.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ChatCompletionRequest, ResolvedConfig } from '../types.js'\nimport type { Logger } from './handler.js'\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')\n}\n\nfunction sendJSON(res: http.ServerResponse, status: number, body: unknown): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\n/**\n * Extract the bearer token from the Authorization header.\n * This is the user's LLM API key — used to forward to the upstream LLM.\n */\nfunction extractBearerToken(req: http.IncomingMessage): string | null {\n const auth = req.headers.authorization\n if (!auth || !auth.startsWith('Bearer ')) return null\n return auth.slice(7)\n}\n\nexport async function handleChatCompletions(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const request = body as ChatCompletionRequest\n\n // Validate required fields\n if (!request.messages || !Array.isArray(request.messages)) {\n sendJSON(res, 400, {\n error: { message: 'messages is required and must be an array', type: 'invalid_request_error' },\n })\n return\n }\n\n // Extract LLM API key from the incoming request\n const llmApiKey = extractBearerToken(req)\n if (!llmApiKey) {\n sendJSON(res, 401, {\n error: { message: 'Authorization header with Bearer token is required', type: 'authentication_error' },\n })\n return\n }\n\n // Compress messages (or passthrough if circuit is open / disabled)\n let messages = request.messages\n let anyCompressed = false\n\n if (config.enabled && !pipeline.isCircuitOpen()) {\n try {\n const compressRoles = new Set(config.compressRoles)\n const result = await compressMessages(\n request.messages,\n pipeline.pipeline,\n pipeline.session,\n compressRoles,\n )\n messages = result.messages\n anyCompressed = result.anyCompressed\n\n if (result.totalTokensSaved > 0) {\n logger.log(`[COMPRESS] Saved ${result.totalTokensSaved} tokens`)\n }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n logger.log('[DEGRADE] Circuit breaker open — passing through directly')\n } else {\n logger.log(`[ERROR] Compression failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n // Fall through with original messages\n messages = request.messages\n }\n }\n\n // Build upstream request\n const upstreamUrl = `${config.upstreamBaseUrl}/v1/chat/completions`\n const upstreamBody = { ...request, messages }\n\n const upstreamHeaders: Record<string, string> = {\n 'Authorization': `Bearer ${llmApiKey}`,\n 'Content-Type': 'application/json',\n }\n\n // Forward streaming preference\n if (request.stream) {\n upstreamHeaders['Accept'] = 'text/event-stream'\n }\n\n try {\n const upstreamResponse = await fetch(upstreamUrl, {\n method: 'POST',\n headers: upstreamHeaders,\n body: JSON.stringify(upstreamBody),\n })\n\n // Handle upstream errors\n if (!upstreamResponse.ok) {\n const errorBody = await upstreamResponse.text()\n setCORSHeaders(res)\n res.writeHead(upstreamResponse.status, {\n 'Content-Type': upstreamResponse.headers.get('Content-Type') || 'application/json',\n })\n res.end(errorBody)\n return\n }\n\n // Streaming response\n if (request.stream && upstreamResponse.body) {\n const learningBuffer = anyCompressed\n ? createStreamLearningBuffer(pipeline.pipeline)\n : null\n\n await pipeSSEResponse(\n upstreamResponse,\n res,\n (text) => learningBuffer?.append(text),\n () => learningBuffer?.flush(),\n )\n return\n }\n\n // Non-streaming response\n const responseBody = await upstreamResponse.text()\n setCORSHeaders(res)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(responseBody)\n\n // Trigger learning from response (fire-and-forget)\n if (anyCompressed) {\n try {\n const parsed = JSON.parse(responseBody)\n const content = parsed?.choices?.[0]?.message?.content\n if (typeof content === 'string' && content.length > 0) {\n pipeline.pipeline.triggerLearning(content)\n }\n } catch {\n // Ignore learning parse errors\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Upstream request failed: ${message}`)\n if (!res.headersSent) {\n sendJSON(res, 502, {\n error: { message: `Failed to reach upstream LLM: ${message}`, type: 'server_error' },\n })\n }\n }\n}\n","import type { CompressionPipeline, Session } from '@cognisos/rsc-sdk'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport type { ChatCompletionMessage, ContentPart } from '../types.js'\n\nexport interface CompressedMessagesResult {\n messages: ChatCompletionMessage[]\n anyCompressed: boolean\n totalTokensSaved: number\n}\n\n/**\n * Walk an array of ChatCompletion messages and compress eligible ones\n * via the RSC CompressionPipeline. Non-eligible roles and non-text\n * content parts pass through unchanged.\n */\nexport async function compressMessages(\n messages: ChatCompletionMessage[],\n pipeline: CompressionPipeline,\n session: Session,\n compressRoles: Set<string>,\n): Promise<CompressedMessagesResult> {\n let anyCompressed = false\n let totalTokensSaved = 0\n\n const compressed = await Promise.all(\n messages.map(async (msg) => {\n if (!compressRoles.has(msg.role)) return msg\n\n // String content\n if (typeof msg.content === 'string') {\n return compressStringContent(msg, pipeline, session, (c, saved) => {\n anyCompressed = anyCompressed || c\n totalTokensSaved += saved\n })\n }\n\n // Array content (vision messages with text + image parts)\n if (Array.isArray(msg.content)) {\n return compressArrayContent(msg, pipeline, session, (c, saved) => {\n anyCompressed = anyCompressed || c\n totalTokensSaved += saved\n })\n }\n\n // null or other content — pass through\n return msg\n }),\n )\n\n return { messages: compressed, anyCompressed, totalTokensSaved }\n}\n\nasync function compressStringContent(\n msg: ChatCompletionMessage,\n pipeline: CompressionPipeline,\n session: Session,\n record: (compressed: boolean, saved: number) => void,\n): Promise<ChatCompletionMessage> {\n try {\n const result = await pipeline.compressForLLM(msg.content as string)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return { ...msg, content: result.text }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n session.recordFailure()\n throw err\n }\n // Other RSC errors — return original text, don't block the request\n session.recordFailure()\n return msg\n }\n}\n\nasync function compressArrayContent(\n msg: ChatCompletionMessage,\n pipeline: CompressionPipeline,\n session: Session,\n record: (compressed: boolean, saved: number) => void,\n): Promise<ChatCompletionMessage> {\n const parts = msg.content as ContentPart[]\n\n const compressedParts = await Promise.all(\n parts.map(async (part) => {\n if (part.type === 'text' && typeof part.text === 'string') {\n try {\n const result = await pipeline.compressForLLM(part.text)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return { ...part, text: result.text }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n session.recordFailure()\n throw err\n }\n session.recordFailure()\n return part\n }\n }\n // Pass through image_url, tool_use, etc.\n return part\n }),\n )\n\n return { ...msg, content: compressedParts }\n}\n","import type { CompressionPipeline } from '@cognisos/rsc-sdk'\n\n/**\n * Creates a buffer that accumulates streamed response text and triggers\n * background learning when the stream completes.\n */\nexport function createStreamLearningBuffer(pipeline: CompressionPipeline) {\n let buffer = ''\n\n return {\n /** Append a text delta from an SSE chunk */\n append(text: string): void {\n buffer += text\n },\n\n /** Flush the buffer — triggers fire-and-forget learning */\n flush(): void {\n if (buffer.length > 0) {\n pipeline.triggerLearning(buffer)\n buffer = ''\n }\n },\n\n /** Get current buffer contents (for testing) */\n getBuffer(): string {\n return buffer\n },\n }\n}\n","import * as http from 'node:http'\n\n/**\n * Pipe an SSE response from an upstream LLM to the client,\n * parsing content deltas for the learning buffer.\n *\n * Writes each chunk immediately — zero buffering, zero added latency.\n */\nexport async function pipeSSEResponse(\n upstreamResponse: Response,\n clientRes: http.ServerResponse,\n onContentDelta: (text: string) => void,\n onComplete: () => void,\n): Promise<void> {\n clientRes.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n })\n\n const reader = upstreamResponse.body!.getReader()\n const decoder = new TextDecoder()\n let lineBuf = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n\n // Write immediately to client\n clientRes.write(chunk)\n\n // Parse SSE lines for learning (best-effort, never blocks the pipe)\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const json = JSON.parse(line.slice(6))\n const content = json?.choices?.[0]?.delta?.content\n if (typeof content === 'string') {\n onContentDelta(content)\n }\n } catch {\n // Malformed SSE data — ignore for learning, chunk already piped\n }\n }\n }\n }\n } finally {\n clientRes.end()\n onComplete()\n }\n}\n","import * as http from 'node:http'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport { compressMessages } from '../rsc/message-compressor.js'\nimport { createStreamLearningBuffer } from '../rsc/learning.js'\nimport { pipeAnthropicSSEResponse } from './anthropic-streaming.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ChatCompletionMessage, ResolvedConfig } from '../types.js'\nimport type { AnthropicMessagesRequest, AnthropicMessage, AnthropicContentBlock } from '../types/anthropic.js'\nimport type { Logger } from './handler.js'\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, anthropic-beta')\n}\n\nfunction sendAnthropicError(res: http.ServerResponse, status: number, type: string, message: string): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ type: 'error', error: { type, message } }))\n}\n\n/**\n * Extract auth headers from incoming request.\n * Supports both x-api-key (API users) and Authorization: Bearer (subscription/OAuth users).\n */\nfunction extractAuthHeaders(req: http.IncomingMessage): Record<string, string> {\n const headers: Record<string, string> = {}\n\n const xApiKey = req.headers['x-api-key']\n if (typeof xApiKey === 'string' && xApiKey.length > 0) {\n headers['x-api-key'] = xApiKey\n }\n\n const auth = req.headers['authorization']\n if (typeof auth === 'string' && auth.length > 0) {\n headers['Authorization'] = auth\n }\n\n return headers\n}\n\n/**\n * Convert Anthropic messages to ChatCompletionMessage[] for the compressor.\n * The structures are compatible — this is a thin adapter.\n */\nfunction convertAnthropicToCompressible(messages: AnthropicMessage[]): ChatCompletionMessage[] {\n return messages.map((msg) => ({\n role: msg.role,\n content: msg.content as string | AnthropicContentBlock[],\n }))\n}\n\n/**\n * Convert compressed ChatCompletionMessage[] back to Anthropic format.\n */\nfunction convertCompressedToAnthropic(messages: ChatCompletionMessage[]): AnthropicMessage[] {\n return messages.map((msg) => ({\n role: msg.role as 'user' | 'assistant',\n content: msg.content as string | AnthropicContentBlock[],\n }))\n}\n\nexport async function handleAnthropicMessages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const request = body as AnthropicMessagesRequest\n\n // Validate required fields\n if (!request.messages || !Array.isArray(request.messages)) {\n sendAnthropicError(res, 400, 'invalid_request_error', 'messages is required and must be an array')\n return\n }\n\n if (typeof request.max_tokens !== 'number') {\n sendAnthropicError(res, 400, 'invalid_request_error', 'max_tokens is required')\n return\n }\n\n // Extract auth headers (x-api-key for API users, Authorization for subscription/OAuth)\n const authHeaders = extractAuthHeaders(req)\n if (Object.keys(authHeaders).length === 0) {\n sendAnthropicError(res, 401, 'authentication_error', 'Authentication required (x-api-key or Authorization header)')\n return\n }\n\n // Compress messages (reuse existing compressor via format conversion)\n let messages = request.messages\n let anyCompressed = false\n\n if (config.enabled && !pipeline.isCircuitOpen()) {\n try {\n const compressRoles = new Set(config.compressRoles)\n const compressible = convertAnthropicToCompressible(request.messages)\n const result = await compressMessages(\n compressible,\n pipeline.pipeline,\n pipeline.session,\n compressRoles,\n )\n messages = convertCompressedToAnthropic(result.messages)\n anyCompressed = result.anyCompressed\n\n if (result.totalTokensSaved > 0) {\n logger.log(`[COMPRESS] Saved ${result.totalTokensSaved} tokens`)\n }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n logger.log('[DEGRADE] Circuit breaker open -- passing through directly')\n } else {\n logger.log(`[ERROR] Compression failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n messages = request.messages\n }\n }\n\n // Build upstream request\n const upstreamUrl = `${config.anthropicUpstreamUrl}/v1/messages`\n const upstreamBody = { ...request, messages }\n\n const upstreamHeaders: Record<string, string> = {\n ...authHeaders,\n 'anthropic-version': (req.headers['anthropic-version'] as string) || '2023-06-01',\n 'Content-Type': 'application/json',\n }\n\n // Forward anthropic-beta header if present\n const betaHeader = req.headers['anthropic-beta']\n if (typeof betaHeader === 'string') {\n upstreamHeaders['anthropic-beta'] = betaHeader\n }\n\n // Log request details for debugging\n const authTypes = Object.keys(authHeaders).join(', ') || 'none'\n logger.log(`[ANTHROPIC] ${request.model} → ${upstreamUrl} (auth: ${authTypes})`)\n\n try {\n const upstreamResponse = await fetch(upstreamUrl, {\n method: 'POST',\n headers: upstreamHeaders,\n body: JSON.stringify(upstreamBody),\n })\n\n // Handle upstream errors\n if (!upstreamResponse.ok) {\n const errorBody = await upstreamResponse.text()\n logger.log(`[ANTHROPIC] Upstream error ${upstreamResponse.status}: ${errorBody.slice(0, 500)}`)\n setCORSHeaders(res)\n res.writeHead(upstreamResponse.status, {\n 'Content-Type': upstreamResponse.headers.get('Content-Type') || 'application/json',\n })\n res.end(errorBody)\n return\n }\n\n // Streaming response\n if (request.stream && upstreamResponse.body) {\n const learningBuffer = anyCompressed\n ? createStreamLearningBuffer(pipeline.pipeline)\n : null\n\n await pipeAnthropicSSEResponse(\n upstreamResponse,\n res,\n (text) => learningBuffer?.append(text),\n () => learningBuffer?.flush(),\n )\n return\n }\n\n // Non-streaming response\n const responseBody = await upstreamResponse.text()\n setCORSHeaders(res)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(responseBody)\n\n // Trigger learning from response (fire-and-forget)\n if (anyCompressed) {\n try {\n const parsed = JSON.parse(responseBody)\n const textBlocks = parsed?.content?.filter(\n (b: AnthropicContentBlock) => b.type === 'text' && typeof b.text === 'string',\n )\n const content = textBlocks?.map((b: AnthropicContentBlock) => b.text).join('')\n if (typeof content === 'string' && content.length > 0) {\n pipeline.pipeline.triggerLearning(content)\n }\n } catch {\n // Ignore learning parse errors\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Upstream request failed: ${message}`)\n if (!res.headersSent) {\n sendAnthropicError(res, 502, 'api_error', `Failed to reach upstream: ${message}`)\n }\n }\n}\n","import * as http from 'node:http'\n\n/**\n * Pipe an Anthropic SSE response from the upstream to the client,\n * parsing content_block_delta events for the learning buffer.\n *\n * Anthropic SSE format:\n * event: content_block_delta\n * data: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello\"}}\n *\n * Writes each chunk immediately — zero buffering, zero added latency.\n */\nexport async function pipeAnthropicSSEResponse(\n upstreamResponse: Response,\n clientRes: http.ServerResponse,\n onContentDelta: (text: string) => void,\n onComplete: () => void,\n): Promise<void> {\n clientRes.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n })\n\n const reader = upstreamResponse.body!.getReader()\n const decoder = new TextDecoder()\n let lineBuf = ''\n let currentEvent = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n\n // Write immediately to client\n clientRes.write(chunk)\n\n // Parse SSE lines for learning (best-effort, never blocks the pipe)\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7).trim()\n } else if (line.startsWith('data: ') && currentEvent === 'content_block_delta') {\n try {\n const json = JSON.parse(line.slice(6))\n if (json?.delta?.type === 'text_delta' && typeof json.delta.text === 'string') {\n onContentDelta(json.delta.text)\n }\n } catch {\n // Malformed data — ignore for learning, chunk already piped\n }\n }\n }\n }\n } finally {\n clientRes.end()\n onComplete()\n }\n}\n","import * as http from 'node:http'\nimport { handleChatCompletions } from './completions.js'\nimport { handleAnthropicMessages } from './messages.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ResolvedConfig } from '../types.js'\n\nexport interface Logger {\n log(message: string): void\n}\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, anthropic-beta')\n res.setHeader('Access-Control-Max-Age', '86400')\n}\n\nfunction sendJSON(res: http.ServerResponse, status: number, body: unknown): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\nfunction readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))\n req.on('error', reject)\n })\n}\n\n/**\n * Passthrough proxy for Anthropic sub-routes (count_tokens, batches, etc.).\n * Forwards the request to upstream Anthropic without modification.\n */\nasync function passthroughAnthropic(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n fullUrl: string,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const upstreamUrl = `${config.anthropicUpstreamUrl}${fullUrl}`\n\n // Forward auth headers\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const xApiKey = req.headers['x-api-key']\n if (typeof xApiKey === 'string') headers['x-api-key'] = xApiKey\n const auth = req.headers['authorization']\n if (typeof auth === 'string') headers['Authorization'] = auth\n const version = req.headers['anthropic-version']\n if (typeof version === 'string') headers['anthropic-version'] = version\n const beta = req.headers['anthropic-beta']\n if (typeof beta === 'string') headers['anthropic-beta'] = beta\n\n try {\n const body = await readBody(req)\n const upstreamRes = await fetch(upstreamUrl, {\n method: 'POST',\n headers,\n body,\n })\n const responseBody = await upstreamRes.text()\n setCORSHeaders(res)\n res.writeHead(upstreamRes.status, {\n 'Content-Type': upstreamRes.headers.get('Content-Type') || 'application/json',\n })\n res.end(responseBody)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Passthrough failed: ${message}`)\n setCORSHeaders(res)\n res.writeHead(502, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ type: 'error', error: { type: 'api_error', message: `Failed to reach upstream: ${message}` } }))\n }\n}\n\nexport function createRequestHandler(\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): (req: http.IncomingMessage, res: http.ServerResponse) => void {\n const startTime = Date.now()\n\n return async (req, res) => {\n try {\n const method = req.method?.toUpperCase() ?? ''\n const fullUrl = req.url ?? ''\n const url = fullUrl.split('?')[0] // Strip query string for route matching\n\n // Log every incoming request\n const authType = req.headers['x-api-key'] ? 'x-api-key' : req.headers['authorization'] ? 'bearer' : 'none'\n logger.log(`[REQUEST] ${method} ${fullUrl} (auth: ${authType})`)\n\n // CORS preflight\n if (method === 'OPTIONS') {\n setCORSHeaders(res)\n res.writeHead(204)\n res.end()\n return\n }\n\n // Health check (extended with session summary for `liminal status` / `liminal summary`)\n if (method === 'GET' && (url === '/health' || url === '/')) {\n const summary = pipeline.getSessionSummary()\n sendJSON(res, 200, {\n status: 'ok',\n version: config.rscApiKey ? 'connected' : 'no-api-key',\n rsc_connected: !pipeline.isCircuitOpen(),\n circuit_state: pipeline.getCircuitState(),\n session_id: summary.sessionId,\n uptime_ms: Date.now() - startTime,\n session: {\n tokens_processed: summary.tokensProcessed,\n tokens_saved: summary.tokensSaved,\n calls_total: summary.totalCalls,\n calls_compressed: summary.compressedCalls,\n calls_skipped: summary.skippedCalls,\n calls_failed: summary.failedCalls,\n patterns_learned: summary.patternsLearned,\n estimated_cost_saved_usd: summary.estimatedCostSaved,\n },\n })\n return\n }\n\n // Model listing — proxy to upstream LLM\n if (method === 'GET' && (url === '/v1/models' || url === '/models')) {\n const llmApiKey = req.headers.authorization?.slice(7)\n if (!llmApiKey) {\n sendJSON(res, 401, {\n error: { message: 'Authorization header with Bearer token is required', type: 'authentication_error' },\n })\n return\n }\n\n try {\n const upstreamRes = await fetch(`${config.upstreamBaseUrl}/v1/models`, {\n headers: { 'Authorization': `Bearer ${llmApiKey}` },\n })\n const body = await upstreamRes.text()\n setCORSHeaders(res)\n res.writeHead(upstreamRes.status, {\n 'Content-Type': upstreamRes.headers.get('Content-Type') || 'application/json',\n })\n res.end(body)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n sendJSON(res, 502, {\n error: { message: `Failed to reach upstream: ${message}`, type: 'server_error' },\n })\n }\n return\n }\n\n // Main route: chat completions\n if (method === 'POST' && (url === '/v1/chat/completions' || url === '/chat/completions')) {\n const body = await readBody(req)\n let parsed: unknown\n try {\n parsed = JSON.parse(body)\n } catch {\n sendJSON(res, 400, {\n error: { message: 'Invalid JSON body', type: 'invalid_request_error' },\n })\n return\n }\n\n await handleChatCompletions(req, res, parsed, pipeline, config, logger)\n return\n }\n\n // Anthropic Messages route\n if (method === 'POST' && (url === '/v1/messages' || url === '/messages')) {\n const body = await readBody(req)\n let parsed: unknown\n try {\n parsed = JSON.parse(body)\n } catch {\n sendJSON(res, 400, {\n type: 'error',\n error: { type: 'invalid_request_error', message: 'Invalid JSON body' },\n })\n return\n }\n\n await handleAnthropicMessages(req, res, parsed, pipeline, config, logger)\n return\n }\n\n // Anthropic passthrough routes (count_tokens, batches, etc.)\n if (method === 'POST' && url.startsWith('/v1/messages/')) {\n await passthroughAnthropic(req, res, fullUrl, config, logger)\n return\n }\n\n // 404\n sendJSON(res, 404, {\n error: { message: `Not found: ${method} ${url}`, type: 'invalid_request_error' },\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Proxy handler error: ${message}`)\n if (!res.headersSent) {\n sendJSON(res, 500, {\n error: { message: 'Internal proxy error', type: 'server_error' },\n })\n }\n }\n }\n}\n","import * as http from 'node:http'\n\nconst MAX_PORT_RETRIES = 5\n\nexport class ProxyServer {\n private server: http.Server | null = null\n private activePort: number | null = null\n private readonly requestedPort: number\n private readonly handler: (req: http.IncomingMessage, res: http.ServerResponse) => void\n\n constructor(\n port: number,\n handler: (req: http.IncomingMessage, res: http.ServerResponse) => void,\n ) {\n this.requestedPort = port\n this.handler = handler\n }\n\n async start(): Promise<number> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < MAX_PORT_RETRIES; attempt++) {\n const port = this.requestedPort + attempt\n try {\n await this.listen(port)\n this.activePort = port\n return port\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err))\n if ((err as NodeJS.ErrnoException).code !== 'EADDRINUSE') {\n throw lastError\n }\n }\n }\n\n throw lastError ?? new Error(`All ports ${this.requestedPort}-${this.requestedPort + MAX_PORT_RETRIES - 1} in use`)\n }\n\n private listen(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = http.createServer(this.handler)\n server.on('error', reject)\n server.listen(port, '127.0.0.1', () => {\n server.removeListener('error', reject)\n this.server = server\n resolve()\n })\n })\n }\n\n async stop(): Promise<void> {\n if (!this.server) return\n return new Promise((resolve) => {\n this.server!.close(() => {\n this.server = null\n this.activePort = null\n resolve()\n })\n })\n }\n\n isRunning(): boolean {\n return this.server !== null && this.server.listening\n }\n\n getPort(): number | null {\n return this.activePort\n }\n}\n","import { appendFileSync, statSync, renameSync, mkdirSync, existsSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { LOG_FILE, LOG_DIR } from '../config/paths.js'\nimport type { Logger } from '../proxy/handler.js'\n\nconst MAX_LOG_SIZE = 10 * 1024 * 1024 // 10 MB\nconst MAX_BACKUPS = 2\n\nexport class FileLogger implements Logger {\n private readonly logFile: string\n private readonly mirrorStdout: boolean\n\n constructor(options?: { logFile?: string; mirrorStdout?: boolean }) {\n this.logFile = options?.logFile ?? LOG_FILE\n this.mirrorStdout = options?.mirrorStdout ?? false\n\n // Ensure log directory exists\n const logDir = dirname(this.logFile)\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true })\n }\n }\n\n log(message: string): void {\n const timestamp = new Date().toISOString().slice(11, 23)\n const line = `[${timestamp}] ${message}\\n`\n\n try {\n appendFileSync(this.logFile, line)\n } catch {\n // If log write fails, try stdout as fallback\n process.stderr.write(`[LOG-WRITE-FAILED] ${line}`)\n }\n\n if (this.mirrorStdout) {\n process.stdout.write(line)\n }\n\n this.rotateIfNeeded()\n }\n\n private rotateIfNeeded(): void {\n try {\n const stats = statSync(this.logFile)\n if (stats.size <= MAX_LOG_SIZE) return\n\n // Rotate: liminal.log -> liminal.log.1 -> liminal.log.2 (drop oldest)\n for (let i = MAX_BACKUPS - 1; i >= 1; i--) {\n const from = `${this.logFile}.${i}`\n const to = `${this.logFile}.${i + 1}`\n if (existsSync(from)) renameSync(from, to)\n }\n renameSync(this.logFile, `${this.logFile}.1`)\n } catch {\n // Rotation failure is non-fatal\n }\n }\n\n getLogFile(): string {\n return this.logFile\n }\n}\n\n/**\n * A simple logger that only writes to stdout (for use during init or when log file isn't available).\n */\nexport class ConsoleLogger implements Logger {\n log(message: string): void {\n const timestamp = new Date().toISOString().slice(11, 23)\n process.stdout.write(`[${timestamp}] ${message}\\n`)\n }\n}\n","import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs'\nimport { fork } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { PID_FILE } from '../config/paths.js'\nimport type { ProxyServer } from '../proxy/server.js'\nimport type { Logger } from '../proxy/handler.js'\n\n/**\n * Write the current process PID to ~/.liminal/liminal.pid.\n */\nexport function writePidFile(pid: number): void {\n writeFileSync(PID_FILE, String(pid), 'utf-8')\n}\n\n/**\n * Read PID from ~/.liminal/liminal.pid. Returns null if file doesn't exist.\n */\nexport function readPidFile(): number | null {\n if (!existsSync(PID_FILE)) return null\n try {\n const content = readFileSync(PID_FILE, 'utf-8').trim()\n const pid = parseInt(content, 10)\n return isNaN(pid) ? null : pid\n } catch {\n return null\n }\n}\n\n/**\n * Remove the PID file.\n */\nexport function removePidFile(): void {\n try {\n if (existsSync(PID_FILE)) unlinkSync(PID_FILE)\n } catch {\n // Ignore — file may already be gone\n }\n}\n\n/**\n * Check if a process with the given PID is alive.\n */\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Check if the Liminal daemon is currently running.\n * Cleans up stale PID files automatically.\n */\nexport function isDaemonRunning(): { running: boolean; pid?: number } {\n const pid = readPidFile()\n if (pid === null) return { running: false }\n\n if (isProcessAlive(pid)) {\n return { running: true, pid }\n }\n\n // Stale PID file — process is dead\n removePidFile()\n return { running: false }\n}\n\n/**\n * Set up signal handlers for graceful shutdown.\n */\nexport function setupSignalHandlers(server: ProxyServer, logger: Logger): void {\n const shutdown = async (signal: string) => {\n logger.log(`[DAEMON] Received ${signal}, shutting down...`)\n try {\n await server.stop()\n } catch {\n // Best-effort server stop\n }\n removePidFile()\n logger.log('[DAEMON] Stopped.')\n process.exit(0)\n }\n\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n process.on('SIGINT', () => shutdown('SIGINT'))\n\n process.on('uncaughtException', (err) => {\n logger.log(`[FATAL] Uncaught exception: ${err.message}`)\n removePidFile()\n process.exit(1)\n })\n\n process.on('unhandledRejection', (reason) => {\n const message = reason instanceof Error ? reason.message : String(reason)\n logger.log(`[FATAL] Unhandled rejection: ${message}`)\n removePidFile()\n process.exit(1)\n })\n}\n\n/**\n * Fork a detached child process to run the daemon in the background.\n * Returns the child PID.\n */\nexport function forkDaemon(binPath: string, extraArgs: string[] = []): number {\n const child = fork(binPath, ['start', '--_forked', ...extraArgs], {\n detached: true,\n stdio: 'ignore',\n })\n\n child.unref()\n return child.pid!\n}\n\n/**\n * Resolve the bin.ts/bin.js entry point path from import.meta.url.\n */\nexport function resolveBinPath(importMetaUrl: string): string {\n return fileURLToPath(importMetaUrl)\n}\n\n/**\n * Sleep for a given number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { loadConfig, applyOverrides, isConfigured } from '../config/loader.js'\nimport { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport { createRequestHandler } from '../proxy/handler.js'\nimport { ProxyServer } from '../proxy/server.js'\nimport { FileLogger } from '../daemon/logger.js'\nimport {\n isDaemonRunning,\n writePidFile,\n setupSignalHandlers,\n forkDaemon,\n resolveBinPath,\n} from '../daemon/lifecycle.js'\nimport type { ResolvedConfig, Tool } from '../types.js'\nimport { printBanner } from '../version.js'\n\nexport async function startCommand(flags: Map<string, string | true>): Promise<void> {\n const isDaemon = flags.has('d') || flags.has('daemon')\n const isForked = flags.has('_forked')\n\n // Check if already running (skip for forked processes — parent already checked)\n if (!isForked) {\n const state = isDaemonRunning()\n if (state.running) {\n console.error(`Liminal daemon is already running (PID ${state.pid}).`)\n console.error('Use \"liminal stop\" first, or \"liminal status\" to check.')\n process.exit(1)\n }\n }\n\n // Check config\n if (!isConfigured()) {\n console.error('Liminal is not configured. Run \"liminal init\" first.')\n process.exit(1)\n }\n\n // Load and apply config\n let config = loadConfig()\n const portOverride = flags.get('port')\n const upstreamOverride = flags.get('upstream')\n config = applyOverrides(config, {\n ...(typeof portOverride === 'string' ? { port: parseInt(portOverride, 10) } : {}),\n ...(typeof upstreamOverride === 'string' ? { upstreamBaseUrl: upstreamOverride } : {}),\n })\n\n // Background mode: fork and exit parent\n if (isDaemon && !isForked) {\n const extraArgs: string[] = []\n if (portOverride) extraArgs.push('--port', String(portOverride))\n if (upstreamOverride) extraArgs.push('--upstream', String(upstreamOverride))\n\n const binPath = resolveBinPath(import.meta.url)\n const childPid = forkDaemon(binPath, extraArgs)\n\n console.log(`Liminal daemon started in background (PID ${childPid})`)\n console.log(`Proxy: http://127.0.0.1:${config.port}/v1`)\n console.log('Logs: ~/.liminal/logs/liminal.log')\n process.exit(0)\n }\n\n // Foreground mode: run the server in this process\n const isForeground = !isDaemon || isForked\n const logger = new FileLogger({ mirrorStdout: isForeground && !isForked })\n\n // Build the resolved config for the proxy\n const resolvedConfig: ResolvedConfig = {\n rscApiKey: config.apiKey,\n rscBaseUrl: config.apiBaseUrl,\n proxyPort: config.port,\n compressionThreshold: config.compressionThreshold,\n compressRoles: config.compressRoles,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs || undefined,\n upstreamBaseUrl: config.upstreamBaseUrl,\n anthropicUpstreamUrl: config.anthropicUpstreamUrl,\n enabled: config.enabled,\n tools: config.tools as Tool[],\n }\n\n // Create RSC pipeline\n const pipeline = new RSCPipelineWrapper({\n rscApiKey: config.apiKey,\n rscBaseUrl: config.apiBaseUrl,\n compressionThreshold: config.compressionThreshold,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs || undefined,\n })\n\n // Wire up pipeline events for logging\n pipeline.events.on('compression', (event) => {\n if (event.tokensSaved > 0) {\n logger.log(`[LIMINAL] Compressed: ${event.tokensSaved} tokens saved (${event.ratio.toFixed(3)} ratio)`)\n }\n })\n pipeline.events.on('compression_skipped', (event) => {\n logger.log(`[LIMINAL] Skipped: ${event.reason}`)\n })\n pipeline.events.on('error', (event) => {\n logger.log(`[LIMINAL] Error: ${event.error.message}`)\n })\n pipeline.events.on('degradation', (event) => {\n logger.log(`[LIMINAL] Circuit ${event.circuitState}: ${event.reason}`)\n })\n\n // Create server\n const handler = createRequestHandler(pipeline, resolvedConfig, logger)\n const server = new ProxyServer(config.port, handler)\n\n // Setup graceful shutdown\n setupSignalHandlers(server, logger)\n\n // Start listening\n try {\n const actualPort = await server.start()\n writePidFile(process.pid)\n\n logger.log(`[DAEMON] Liminal proxy started on http://127.0.0.1:${actualPort}`)\n logger.log(`[DAEMON] Upstream (OpenAI): ${config.upstreamBaseUrl}`)\n logger.log(`[DAEMON] Upstream (Anthropic): ${config.anthropicUpstreamUrl}`)\n logger.log(`[DAEMON] Liminal API: ${config.apiBaseUrl}`)\n logger.log(`[DAEMON] PID: ${process.pid}`)\n\n if (isForeground && !isForked) {\n printBanner()\n console.log(` Liminal proxy running on http://127.0.0.1:${actualPort}/v1`)\n console.log(` Upstream: ${config.upstreamBaseUrl}`)\n console.log()\n console.log(' Point your AI tool\\'s base URL here. Press Ctrl+C to stop.')\n console.log()\n }\n\n // Check RSC API health on startup\n const healthy = await pipeline.healthCheck()\n if (healthy) {\n logger.log('[DAEMON] Liminal API health check: OK')\n } else {\n logger.log('[DAEMON] Liminal API health check: FAILED (will retry on first request)')\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.error(`Failed to start proxy: ${message}`)\n process.exit(1)\n }\n}\n","import {\n isDaemonRunning,\n readPidFile,\n removePidFile,\n isProcessAlive,\n sleep,\n} from '../daemon/lifecycle.js'\n\nexport async function stopCommand(): Promise<void> {\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal daemon is not running.')\n return\n }\n\n const pid = state.pid\n console.log(`Stopping Liminal daemon (PID ${pid})...`)\n\n // Send SIGTERM for graceful shutdown\n try {\n process.kill(pid, 'SIGTERM')\n } catch {\n // Process may have already exited\n removePidFile()\n console.log('Liminal daemon stopped.')\n return\n }\n\n // Poll for up to 5 seconds\n for (let i = 0; i < 25; i++) {\n await sleep(200)\n if (!isProcessAlive(pid)) {\n removePidFile()\n console.log(`Liminal daemon stopped (PID ${pid}).`)\n return\n }\n }\n\n // Force kill after timeout\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n // Already dead\n }\n\n removePidFile()\n console.log(`Liminal daemon force-killed (PID ${pid}).`)\n}\n","import { isDaemonRunning } from '../daemon/lifecycle.js'\nimport { loadConfig, isConfigured } from '../config/loader.js'\n\nexport async function statusCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log('Liminal: not configured')\n console.log('Run \"liminal init\" to set up.')\n return\n }\n\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal Daemon: stopped')\n console.log('Run \"liminal start\" to start the proxy.')\n return\n }\n\n const config = loadConfig()\n const port = config.port\n\n // Try to reach the daemon's /health endpoint\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(3000),\n })\n const data = await res.json() as {\n status: string\n circuit_state: string\n session_id: string\n uptime_ms: number\n session?: {\n tokens_processed: number\n tokens_saved: number\n calls_total: number\n calls_compressed: number\n calls_skipped: number\n calls_failed: number\n }\n }\n\n const uptime = formatUptime(data.uptime_ms)\n\n console.log(`Liminal Daemon: running (PID ${state.pid}, port ${port})`)\n console.log(`Circuit: ${data.circuit_state}`)\n console.log(`Session: ${data.session_id}`)\n console.log(`Uptime: ${uptime}`)\n\n if (data.session) {\n const s = data.session\n const savingsPercent = s.tokens_processed > 0\n ? ((s.tokens_saved / s.tokens_processed) * 100).toFixed(1)\n : '0.0'\n console.log()\n console.log(`Tokens: ${s.tokens_processed.toLocaleString()} processed, ${s.tokens_saved.toLocaleString()} saved (${savingsPercent}%)`)\n console.log(`Calls: ${s.calls_total} total (${s.calls_compressed} compressed, ${s.calls_skipped} skipped, ${s.calls_failed} failed)`)\n }\n } catch {\n // Can't reach the daemon, but PID is alive — might still be starting\n console.log(`Liminal Daemon: running (PID ${state.pid}, port ${port})`)\n console.log('Circuit: unknown (could not reach /health)')\n }\n}\n\nfunction formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`\n if (hours > 0) return `${hours}h ${minutes % 60}m`\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`\n return `${seconds}s`\n}\n","import { isDaemonRunning } from '../daemon/lifecycle.js'\nimport { loadConfig, isConfigured } from '../config/loader.js'\n\nexport async function summaryCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log('Liminal is not configured. Run \"liminal init\" first.')\n return\n }\n\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal daemon is not running. Start it with \"liminal start\".')\n return\n }\n\n const config = loadConfig()\n const port = config.port\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(3000),\n })\n const data = await res.json() as {\n circuit_state: string\n session_id: string\n uptime_ms: number\n session?: {\n tokens_processed: number\n tokens_saved: number\n calls_total: number\n calls_compressed: number\n calls_skipped: number\n calls_failed: number\n patterns_learned: number\n estimated_cost_saved_usd: number\n }\n }\n\n const uptime = formatUptime(data.uptime_ms)\n\n console.log()\n console.log(` Session: ${data.session_id}`)\n console.log(` Uptime: ${uptime}`)\n console.log()\n\n if (data.session) {\n const s = data.session\n const savingsPercent = s.tokens_processed > 0\n ? ((s.tokens_saved / s.tokens_processed) * 100).toFixed(1)\n : '0.0'\n const compressionRate = s.calls_total > 0\n ? ((s.calls_compressed / s.calls_total) * 100).toFixed(0)\n : '0'\n\n console.log(' Compression:')\n console.log(` Tokens processed: ${s.tokens_processed.toLocaleString()}`)\n console.log(` Tokens saved: ${s.tokens_saved.toLocaleString()} (${savingsPercent}%)`)\n console.log(` Compression rate: ${compressionRate}% of calls compressed`)\n console.log(` Patterns learned: ${s.patterns_learned.toLocaleString()}`)\n console.log()\n console.log(' Calls:')\n console.log(` Total: ${s.calls_total}`)\n console.log(` Compressed: ${s.calls_compressed}`)\n console.log(` Skipped: ${s.calls_skipped}`)\n console.log(` Failed: ${s.calls_failed}`)\n console.log()\n console.log(' Cost Savings:')\n console.log(` Estimated: $${s.estimated_cost_saved_usd.toFixed(4)} USD`)\n console.log()\n } else {\n console.log(' No session data available yet.')\n console.log()\n }\n\n console.log(` Circuit: ${data.circuit_state}`)\n console.log(` API: ${config.apiBaseUrl}`)\n console.log(` Upstream: ${config.upstreamBaseUrl}`)\n console.log()\n } catch {\n console.error('Could not reach the Liminal daemon. Is it running?')\n console.error(`Tried http://127.0.0.1:${port}/health`)\n process.exit(1)\n }\n}\n\nfunction formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`\n if (hours > 0) return `${hours}h ${minutes % 60}m`\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`\n return `${seconds}s`\n}\n","import { loadConfig, saveConfig, isConfigured, maskApiKey } from '../config/loader.js'\nimport { CONFIGURABLE_KEYS } from '../config/schema.js'\nimport { CONFIG_FILE } from '../config/paths.js'\n\nexport async function configCommand(flags: Map<string, string | true>): Promise<void> {\n const getKey = flags.get('get')\n const setKv = flags.get('set')\n\n // rsc config --get <key>\n if (typeof getKey === 'string') {\n if (!isConfigured()) {\n console.error('Liminal is not configured. Run \"liminal init\" first.')\n process.exit(1)\n }\n const config = loadConfig()\n const value = (config as unknown as Record<string, unknown>)[getKey]\n if (value === undefined) {\n console.error(`Unknown config key: ${getKey}`)\n process.exit(1)\n }\n console.log(getKey === 'apiKey' ? maskApiKey(String(value)) : String(value))\n return\n }\n\n // rsc config --set <key>=<value>\n if (typeof setKv === 'string') {\n const eqIdx = setKv.indexOf('=')\n if (eqIdx === -1) {\n console.error('Usage: liminal config --set key=value')\n process.exit(1)\n }\n const key = setKv.slice(0, eqIdx)\n const rawValue = setKv.slice(eqIdx + 1)\n\n if (!CONFIGURABLE_KEYS.has(key) && key !== 'apiKey') {\n console.error(`Unknown or non-configurable key: ${key}`)\n console.error(`Configurable keys: ${[...CONFIGURABLE_KEYS].join(', ')}`)\n process.exit(1)\n }\n\n // Parse value based on key type\n let parsedValue: unknown = rawValue\n if (key === 'port' || key === 'compressionThreshold' || key === 'latencyBudgetMs') {\n parsedValue = parseInt(rawValue, 10)\n if (isNaN(parsedValue as number)) {\n console.error(`Invalid number for ${key}: ${rawValue}`)\n process.exit(1)\n }\n } else if (key === 'learnFromResponses' || key === 'enabled') {\n parsedValue = rawValue === 'true' || rawValue === '1'\n } else if (key === 'compressRoles') {\n parsedValue = rawValue.split(',').map((s) => s.trim())\n }\n\n saveConfig({ [key]: parsedValue })\n console.log(`Set ${key} = ${key === 'apiKey' ? maskApiKey(rawValue) : rawValue}`)\n return\n }\n\n // rsc config (no flags) — show all\n if (!isConfigured()) {\n console.log(`Liminal is not configured. Run \"liminal init\" first.`)\n console.log(`Config file: ${CONFIG_FILE}`)\n return\n }\n\n const config = loadConfig()\n console.log()\n console.log(` Config: ${CONFIG_FILE}`)\n console.log()\n console.log(` apiKey: ${maskApiKey(config.apiKey)}`)\n console.log(` apiBaseUrl: ${config.apiBaseUrl}`)\n console.log(` upstreamBaseUrl: ${config.upstreamBaseUrl}`)\n console.log(` anthropicUpstreamUrl: ${config.anthropicUpstreamUrl}`)\n console.log(` tools: ${config.tools.length > 0 ? config.tools.join(', ') : '(none)'}`)\n console.log(` port: ${config.port}`)\n console.log(` compressionThreshold: ${config.compressionThreshold}`)\n console.log(` compressRoles: ${config.compressRoles.join(', ')}`)\n console.log(` learnFromResponses: ${config.learnFromResponses}`)\n console.log(` latencyBudgetMs: ${config.latencyBudgetMs || 'auto'}`)\n console.log(` enabled: ${config.enabled}`)\n console.log()\n}\n","import { readFileSync, existsSync, statSync, createReadStream } from 'node:fs'\nimport { watchFile, unwatchFile } from 'node:fs'\nimport { LOG_FILE } from '../config/paths.js'\n\nexport async function logsCommand(flags: Map<string, string | true>): Promise<void> {\n const follow = flags.has('follow') || flags.has('f')\n const linesFlag = flags.get('lines') ?? flags.get('n')\n const lines = typeof linesFlag === 'string' ? parseInt(linesFlag, 10) : 50\n\n if (!existsSync(LOG_FILE)) {\n console.log('No log file found. Start the daemon with \"liminal start\" to generate logs.')\n return\n }\n\n // Read and display last N lines\n const content = readFileSync(LOG_FILE, 'utf-8')\n const allLines = content.split('\\n')\n const tail = allLines.slice(-lines - 1) // -1 to account for trailing newline\n process.stdout.write(tail.join('\\n'))\n\n if (!follow) return\n\n // Follow mode: watch for changes and stream new content\n let lastSize = statSync(LOG_FILE).size\n\n watchFile(LOG_FILE, { interval: 500 }, (curr) => {\n if (curr.size > lastSize) {\n const stream = createReadStream(LOG_FILE, { start: lastSize, encoding: 'utf-8' })\n stream.on('data', (chunk) => process.stdout.write(chunk as string))\n stream.on('end', () => { lastSize = curr.size })\n } else if (curr.size < lastSize) {\n // File was rotated — read from beginning\n lastSize = 0\n }\n })\n\n // Keep the process alive and handle Ctrl+C\n process.on('SIGINT', () => {\n unwatchFile(LOG_FILE)\n process.exit(0)\n })\n\n // Block forever\n await new Promise(() => {})\n}\n","import { VERSION } from './version.js'\nimport { initCommand } from './commands/init.js'\nimport { loginCommand } from './commands/login.js'\nimport { logoutCommand } from './commands/logout.js'\nimport { startCommand } from './commands/start.js'\nimport { stopCommand } from './commands/stop.js'\nimport { statusCommand } from './commands/status.js'\nimport { summaryCommand } from './commands/summary.js'\nimport { configCommand } from './commands/config.js'\nimport { logsCommand } from './commands/logs.js'\n\nconst USAGE = `\n liminal v${VERSION} — Transparent LLM context compression proxy\n\n Usage:\n liminal init Set up Liminal (login, config)\n liminal login Log in or create an account\n liminal logout Log out of your account\n liminal start [-d] [--port PORT] Start the compression proxy\n liminal stop Stop the running proxy\n liminal status Show proxy health and stats\n liminal summary Detailed session metrics\n liminal config [--set k=v] [--get k] View or edit configuration\n liminal logs [--follow] [--lines N] View proxy logs\n\n Options:\n -h, --help Show this help message\n -v, --version Show version number\n\n Getting started:\n 1. liminal init # Log in + select tools\n 2. liminal start # Start the proxy\n 3. Connect your AI tools:\n Claude Code: export ANTHROPIC_BASE_URL=http://localhost:3141\n Codex: export OPENAI_BASE_URL=http://localhost:3141/v1\n Cursor: Settings > Models > Base URL > http://localhost:3141/v1\n`\n\nfunction parseArgs(argv: string[]): { command: string; flags: Map<string, string | true> } {\n const command = argv[2] ?? ''\n const flags = new Map<string, string | true>()\n\n for (let i = 3; i < argv.length; i++) {\n const arg = argv[i]\n if (arg.startsWith('--')) {\n const key = arg.slice(2)\n // Check if next arg is a value (not another flag)\n if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {\n flags.set(key, argv[i + 1])\n i++\n } else {\n flags.set(key, true)\n }\n } else if (arg.startsWith('-') && arg.length === 2) {\n const key = arg.slice(1)\n if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {\n flags.set(key, argv[i + 1])\n i++\n } else {\n flags.set(key, true)\n }\n }\n }\n\n return { command, flags }\n}\n\nasync function main(): Promise<void> {\n const { command, flags } = parseArgs(process.argv)\n\n // Global flags — handle --help and --version as both commands and flags\n if (flags.has('h') || flags.has('help') || command === 'help' || command === '--help' || command === '-h') {\n console.log(USAGE)\n process.exit(0)\n }\n\n if (flags.has('v') || flags.has('version') || command === 'version' || command === '--version' || command === '-v') {\n console.log(VERSION)\n process.exit(0)\n }\n\n try {\n switch (command) {\n case 'init':\n await initCommand()\n break\n\n case 'login':\n await loginCommand()\n break\n\n case 'logout':\n await logoutCommand()\n break\n\n case 'start':\n await startCommand(flags)\n break\n\n case 'stop':\n await stopCommand()\n break\n\n case 'status':\n await statusCommand()\n break\n\n case 'summary':\n await summaryCommand()\n break\n\n case 'config':\n await configCommand(flags)\n break\n\n case 'logs':\n await logsCommand(flags)\n break\n\n case '':\n console.log(USAGE)\n process.exit(0)\n break\n\n default:\n console.error(`Unknown command: ${command}`)\n console.log(USAGE)\n process.exit(1)\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.error(`Error: ${message}`)\n process.exit(1)\n }\n}\n\nmain()\n"],"mappings":"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","names":["createInterface","stdin","stdout","existsSync","readFileSync","join","homedir","stdin","stdout","homedir","join","existsSync","readFileSync","createInterface","stdin","stdout","RSCCircuitOpenError","RSCCircuitOpenError","RSCCircuitOpenError","setCORSHeaders","RSCCircuitOpenError","setCORSHeaders","sendJSON","appendFileSync","mkdirSync","existsSync","dirname","dirname","existsSync","mkdirSync","appendFileSync","readFileSync","writeFileSync","existsSync","writeFileSync","existsSync","readFileSync","formatUptime","config","readFileSync","existsSync","statSync","existsSync","readFileSync","statSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/config/loader.ts","../src/config/paths.ts","../src/config/schema.ts","../src/config/shell.ts","../src/ui/prompts.ts","../src/commands/login.ts","../src/auth/supabase.ts","../src/connectors/claude-code.ts","../src/connectors/codex.ts","../src/connectors/cursor.ts","../src/connectors/openai-compatible.ts","../src/connectors/index.ts","../src/commands/init.ts","../src/commands/logout.ts","../src/rsc/pipeline.ts","../src/proxy/completions.ts","../src/rsc/message-compressor.ts","../src/rsc/content-segmenter.ts","../src/rsc/learning.ts","../src/proxy/streaming.ts","../src/proxy/messages.ts","../src/proxy/anthropic-streaming.ts","../src/proxy/responses.ts","../src/proxy/responses-streaming.ts","../src/proxy/handler.ts","../src/proxy/server.ts","../src/daemon/logger.ts","../src/daemon/lifecycle.ts","../src/commands/start.ts","../src/commands/stop.ts","../src/commands/status.ts","../src/commands/summary.ts","../src/commands/config.ts","../src/commands/logs.ts","../src/commands/uninstall.ts","../src/bin.ts"],"sourcesContent":["declare const __VERSION__: string\nexport const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.2.1'\n\n// FIGlet-style \"LIMINAL\" banner\nconst BANNER_LINES = [\n ' ___ ___ _____ ______ ___ ________ ________ ___',\n '|\\\\ \\\\ |\\\\ \\\\|\\\\ _ \\\\ _ \\\\|\\\\ \\\\|\\\\ ___ \\\\|\\\\ __ \\\\|\\\\ \\\\',\n '\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\\\\\__\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ \\\\|\\\\ \\\\ \\\\ \\\\',\n ' \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\|__| \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ __ \\\\ \\\\ \\\\',\n ' \\\\ \\\\ \\\\____\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\____',\n ' \\\\ \\\\_______\\\\ \\\\__\\\\ \\\\__\\\\ \\\\ \\\\__\\\\ \\\\__\\\\ \\\\__\\\\\\\\ \\\\__\\\\ \\\\__\\\\ \\\\__\\\\ \\\\_______\\\\',\n ' \\\\|_______|\\\\|__|\\\\|__| \\\\|__|\\\\|__|\\\\|__| \\\\|__|\\\\|__|\\\\|__|\\\\|_______|',\n]\n\nexport function printBanner(): void {\n console.log()\n for (const line of BANNER_LINES) {\n console.log(line)\n }\n console.log()\n console.log(` v${VERSION} -- brought to you by Cognisos`)\n console.log()\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { LIMINAL_DIR, CONFIG_FILE, LOG_DIR } from './paths.js'\nimport { DEFAULTS } from './schema.js'\nimport type { RSCConfig } from './schema.js'\n\n/**\n * Load config from ~/.liminal/config.json, merged with defaults and env var overrides.\n * Priority: env vars > config file > defaults\n */\nexport function loadConfig(): RSCConfig {\n let fileConfig: Partial<RSCConfig> = {}\n\n if (existsSync(CONFIG_FILE)) {\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8')\n fileConfig = JSON.parse(raw)\n } catch {\n // Corrupted config file — fall through to defaults\n }\n }\n\n const merged: RSCConfig = {\n apiKey: fileConfig.apiKey ?? '',\n apiBaseUrl: DEFAULTS.apiBaseUrl,\n upstreamBaseUrl: DEFAULTS.upstreamBaseUrl,\n anthropicUpstreamUrl: DEFAULTS.anthropicUpstreamUrl,\n port: DEFAULTS.port,\n compressionThreshold: DEFAULTS.compressionThreshold,\n compressRoles: DEFAULTS.compressRoles,\n learnFromResponses: DEFAULTS.learnFromResponses,\n latencyBudgetMs: DEFAULTS.latencyBudgetMs,\n enabled: DEFAULTS.enabled,\n tools: DEFAULTS.tools,\n ...fileConfig,\n }\n\n // Environment variable overrides\n if (process.env.LIMINAL_API_KEY) merged.apiKey = process.env.LIMINAL_API_KEY\n if (process.env.LIMINAL_API_URL) merged.apiBaseUrl = process.env.LIMINAL_API_URL\n if (process.env.LIMINAL_UPSTREAM_URL) merged.upstreamBaseUrl = process.env.LIMINAL_UPSTREAM_URL\n if (process.env.LIMINAL_ANTHROPIC_URL) merged.anthropicUpstreamUrl = process.env.LIMINAL_ANTHROPIC_URL\n if (process.env.LIMINAL_PORT) merged.port = parseInt(process.env.LIMINAL_PORT, 10)\n\n return merged\n}\n\n/**\n * Apply CLI flag overrides on top of loaded config.\n */\nexport function applyOverrides(\n config: RSCConfig,\n overrides: Partial<Pick<RSCConfig, 'port' | 'upstreamBaseUrl'>>,\n): RSCConfig {\n return { ...config, ...overrides }\n}\n\n/**\n * Save config to ~/.liminal/config.json. Creates ~/.liminal/ and ~/.liminal/logs/ if needed.\n */\nexport function saveConfig(config: Partial<RSCConfig>): void {\n ensureDirectories()\n\n let existing: Partial<RSCConfig> = {}\n if (existsSync(CONFIG_FILE)) {\n try {\n existing = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'))\n } catch {\n // Overwrite corrupted file\n }\n }\n\n const merged = { ...existing, ...config }\n writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + '\\n', { encoding: 'utf-8', mode: 0o600 })\n try { chmodSync(CONFIG_FILE, 0o600) } catch { /* best effort */ }\n}\n\n/**\n * Ensure ~/.liminal/ and ~/.liminal/logs/ directories exist.\n */\nexport function ensureDirectories(): void {\n if (!existsSync(LIMINAL_DIR)) mkdirSync(LIMINAL_DIR, { recursive: true, mode: 0o700 })\n if (!existsSync(LOG_DIR)) mkdirSync(LOG_DIR, { recursive: true, mode: 0o700 })\n // Ensure parent of config file exists\n const configDir = dirname(CONFIG_FILE)\n if (!existsSync(configDir)) mkdirSync(configDir, { recursive: true })\n}\n\n/**\n * Check if a valid config file exists with an API key.\n */\nexport function isConfigured(): boolean {\n try {\n const config = loadConfig()\n return config.apiKey.length > 0\n } catch {\n return false\n }\n}\n\n/**\n * Mask an API key for display: show first 8 chars + last 4.\n */\nexport function maskApiKey(key: string): string {\n if (key.length <= 12) return '****'\n return key.slice(0, 8) + '...' + key.slice(-4)\n}\n","import { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport const LIMINAL_DIR = join(homedir(), '.liminal')\nexport const CONFIG_FILE = join(LIMINAL_DIR, 'config.json')\nexport const PID_FILE = join(LIMINAL_DIR, 'liminal.pid')\nexport const LOG_DIR = join(LIMINAL_DIR, 'logs')\nexport const LOG_FILE = join(LOG_DIR, 'liminal.log')\n","export interface RSCConfig {\n apiKey: string\n apiBaseUrl: string\n upstreamBaseUrl: string\n anthropicUpstreamUrl: string\n port: number\n compressionThreshold: number\n compressRoles: string[]\n learnFromResponses: boolean\n latencyBudgetMs: number\n enabled: boolean\n tools: string[]\n}\n\nexport const DEFAULTS: Omit<RSCConfig, 'apiKey'> = {\n apiBaseUrl: 'https://api.cognisos.ai',\n upstreamBaseUrl: 'https://api.openai.com',\n anthropicUpstreamUrl: 'https://api.anthropic.com',\n port: 3141,\n compressionThreshold: 100,\n compressRoles: ['user'],\n learnFromResponses: true,\n latencyBudgetMs: 5000,\n enabled: true,\n tools: [],\n}\n\n/** Keys that can be set via `liminal config --set` */\nexport const CONFIGURABLE_KEYS = new Set<string>([\n 'apiBaseUrl',\n 'upstreamBaseUrl',\n 'anthropicUpstreamUrl',\n 'port',\n 'compressionThreshold',\n 'compressRoles',\n 'learnFromResponses',\n 'latencyBudgetMs',\n 'enabled',\n 'tools',\n])\n","/**\n * Shell profile detection and modification utilities.\n * Shared by init (append exports) and uninstall (remove exports).\n */\n\nimport { existsSync, readFileSync, writeFileSync, appendFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\n\nexport interface ShellProfile {\n name: string\n path: string\n}\n\nconst LIMINAL_BLOCK_HEADER = '# Liminal — route AI tools through compression proxy'\n\n/**\n * Detect the user's shell profile file.\n */\nexport function detectShellProfile(): ShellProfile | null {\n const shell = process.env.SHELL || ''\n const home = homedir()\n\n if (shell.endsWith('/zsh')) {\n return { name: '~/.zshrc', path: join(home, '.zshrc') }\n }\n\n if (shell.endsWith('/bash')) {\n const bashProfile = join(home, '.bash_profile')\n if (existsSync(bashProfile)) {\n return { name: '~/.bash_profile', path: bashProfile }\n }\n return { name: '~/.bashrc', path: join(home, '.bashrc') }\n }\n\n const candidates: ShellProfile[] = [\n { name: '~/.zshrc', path: join(home, '.zshrc') },\n { name: '~/.bashrc', path: join(home, '.bashrc') },\n { name: '~/.profile', path: join(home, '.profile') },\n ]\n\n for (const c of candidates) {\n if (existsSync(c.path)) return c\n }\n\n return null\n}\n\n/**\n * Check if a line already exists in a file.\n */\nexport function lineExistsInFile(filePath: string, line: string): boolean {\n if (!existsSync(filePath)) return false\n try {\n const content = readFileSync(filePath, 'utf-8')\n return content.includes(line)\n } catch {\n return false\n }\n}\n\n/**\n * Append export lines to shell profile with a Liminal comment header.\n * Only appends lines that don't already exist.\n */\nexport function appendToShellProfile(profile: ShellProfile, lines: string[]): string[] {\n const newLines = lines.filter((line) => !lineExistsInFile(profile.path, line))\n if (newLines.length === 0) return []\n\n const block = [\n '',\n LIMINAL_BLOCK_HEADER,\n ...newLines,\n ].join('\\n') + '\\n'\n\n appendFileSync(profile.path, block, 'utf-8')\n return newLines\n}\n\n/**\n * Remove all Liminal-related lines from a shell profile.\n * Removes the header comment and any export lines containing Liminal proxy URLs.\n * Returns the lines that were removed.\n */\nexport function removeLiminalFromShellProfile(profile: ShellProfile): string[] {\n if (!existsSync(profile.path)) return []\n\n let content: string\n try {\n content = readFileSync(profile.path, 'utf-8')\n } catch {\n return []\n }\n\n const lines = content.split('\\n')\n const removed: string[] = []\n const kept: string[] = []\n\n for (const line of lines) {\n if (line.trim() === LIMINAL_BLOCK_HEADER) {\n removed.push(line)\n continue\n }\n\n // Match Liminal proxy export lines:\n // export ANTHROPIC_BASE_URL=http://127.0.0.1:XXXX\n // export OPENAI_BASE_URL=http://127.0.0.1:XXXX/v1\n if (isLiminalExportLine(line)) {\n removed.push(line)\n continue\n }\n\n kept.push(line)\n }\n\n if (removed.length > 0) {\n // Clean up consecutive blank lines left by removal\n const cleaned = kept.join('\\n').replace(/\\n{3,}/g, '\\n\\n')\n writeFileSync(profile.path, cleaned, 'utf-8')\n }\n\n return removed\n}\n\n/**\n * Check if a line is a Liminal proxy export.\n */\nfunction isLiminalExportLine(line: string): boolean {\n const trimmed = line.trim()\n if (!trimmed.startsWith('export ')) return false\n // Match export ANTHROPIC_BASE_URL=http://127.0.0.1:XXXX or similar\n if (trimmed.includes('ANTHROPIC_BASE_URL=http://127.0.0.1:')) return true\n if (trimmed.includes('OPENAI_BASE_URL=http://127.0.0.1:')) return true\n return false\n}\n\n/**\n * Find all Liminal export lines currently in a shell profile.\n */\nexport function findLiminalExportsInProfile(profile: ShellProfile): string[] {\n if (!existsSync(profile.path)) return []\n try {\n const content = readFileSync(profile.path, 'utf-8')\n return content.split('\\n').filter(isLiminalExportLine)\n } catch {\n return []\n }\n}\n","/**\n * Lightweight interactive terminal prompts — zero external dependencies.\n * Uses raw stdin mode for arrow-key navigation.\n */\n\n// ─── ANSI escape sequences ───────────────────────────────────────────\n\nconst ANSI = {\n HIDE_CURSOR: '\\x1b[?25l',\n SHOW_CURSOR: '\\x1b[?25h',\n CLEAR_LINE: '\\x1b[2K',\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m',\n CYAN: '\\x1b[36m',\n RESET: '\\x1b[0m',\n moveUp: (n: number) => (n > 0 ? `\\x1b[${n}A` : ''),\n} as const\n\n// ─── Key parsing ─────────────────────────────────────────────────────\n\nexport type KeyPress =\n | { type: 'up' }\n | { type: 'down' }\n | { type: 'enter' }\n | { type: 'space' }\n | { type: 'escape' }\n | { type: 'ctrlc' }\n | { type: 'backspace' }\n | { type: 'char'; char: string }\n | { type: 'other' }\n\nexport function parseKey(data: Buffer): KeyPress {\n if (data.length === 0) return { type: 'other' }\n\n // Ctrl+C\n if (data[0] === 0x03) return { type: 'ctrlc' }\n\n // Arrow keys: ESC [ A/B\n if (data.length >= 3 && data[0] === 0x1b && data[1] === 0x5b) {\n if (data[2] === 0x41) return { type: 'up' }\n if (data[2] === 0x42) return { type: 'down' }\n return { type: 'other' }\n }\n\n // Standalone Escape\n if (data.length === 1 && data[0] === 0x1b) return { type: 'escape' }\n\n // Enter\n if (data[0] === 0x0d || data[0] === 0x0a) return { type: 'enter' }\n\n // Space\n if (data[0] === 0x20) return { type: 'space' }\n\n // Backspace (DEL on macOS)\n if (data[0] === 0x7f || data[0] === 0x08) return { type: 'backspace' }\n\n // Printable ASCII characters (0x21-0x7e)\n if (data.length === 1 && data[0] >= 0x21 && data[0] <= 0x7e) {\n return { type: 'char', char: String.fromCharCode(data[0]) }\n }\n\n return { type: 'other' }\n}\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface SelectOption<T> {\n label: string\n value: T\n description?: string\n}\n\nexport interface MultiSelectOption<T> extends SelectOption<T> {\n default?: boolean\n}\n\ninterface Streams {\n stdin: NodeJS.ReadableStream & { setRawMode?: (mode: boolean) => void; isTTY?: boolean }\n stdout: { write: (s: string) => boolean }\n}\n\ninterface SelectConfig<T> {\n message: string\n options: SelectOption<T>[]\n defaultIndex?: number\n _streams?: Streams\n}\n\ninterface MultiSelectConfig<T> {\n message: string\n options: MultiSelectOption<T>[]\n _streams?: Streams\n}\n\n// ─── Render helpers ──────────────────────────────────────────────────\n\nexport interface RenderResult {\n text: string\n lineCount: number\n}\n\nexport function renderSelect<T>(\n options: SelectOption<T>[],\n cursorIndex: number,\n message: string,\n): RenderResult {\n const lines: string[] = []\n lines.push(` ${ANSI.BOLD}${message}${ANSI.RESET}`)\n lines.push('')\n\n const maxLabel = Math.max(...options.map((o) => o.label.length))\n\n for (let i = 0; i < options.length; i++) {\n const focused = i === cursorIndex\n const pointer = focused ? `${ANSI.CYAN}->${ANSI.RESET}` : ' '\n const label = focused\n ? `${ANSI.BOLD}${options[i].label.padEnd(maxLabel)}${ANSI.RESET}`\n : `${options[i].label.padEnd(maxLabel)}`\n const desc = options[i].description\n ? ` ${ANSI.DIM}${options[i].description}${ANSI.RESET}`\n : ''\n lines.push(` ${pointer} ${label}${desc}`)\n }\n\n lines.push('')\n return { text: lines.join('\\n'), lineCount: lines.length }\n}\n\nexport function renderMultiSelect<T>(\n options: MultiSelectOption<T>[],\n cursorIndex: number,\n selected: Set<number>,\n message: string,\n): RenderResult {\n const lines: string[] = []\n lines.push(` ${ANSI.BOLD}${message}${ANSI.RESET}`)\n lines.push('')\n\n const maxLabel = Math.max(...options.map((o) => o.label.length))\n\n for (let i = 0; i < options.length; i++) {\n const focused = i === cursorIndex\n const checked = selected.has(i)\n const pointer = focused ? `${ANSI.CYAN}->${ANSI.RESET}` : ' '\n const box = checked\n ? `${ANSI.CYAN}[x]${ANSI.RESET}`\n : `${ANSI.DIM}[ ]${ANSI.RESET}`\n const label = focused\n ? `${ANSI.BOLD}${options[i].label.padEnd(maxLabel)}${ANSI.RESET}`\n : `${options[i].label.padEnd(maxLabel)}`\n const desc = options[i].description\n ? ` ${ANSI.DIM}${options[i].description}${ANSI.RESET}`\n : ''\n lines.push(` ${pointer} ${box} ${label}${desc}`)\n }\n\n lines.push('')\n lines.push(` ${ANSI.DIM}↑/↓ Navigate ${ANSI.RESET}${ANSI.CYAN}Space${ANSI.RESET}${ANSI.DIM} Select ${ANSI.RESET}${ANSI.CYAN}Enter${ANSI.RESET}${ANSI.DIM} Confirm${ANSI.RESET}`)\n lines.push('')\n return { text: lines.join('\\n'), lineCount: lines.length }\n}\n\n// ─── Raw mode lifecycle ──────────────────────────────────────────────\n\nfunction withRawMode<T>(\n streams: Streams,\n handler: (\n resolve: (value: T) => void,\n ) => (key: KeyPress) => void,\n): Promise<T> {\n const { stdin, stdout } = streams\n\n return new Promise<T>((resolve, reject) => {\n let cleaned = false\n\n function cleanup() {\n if (cleaned) return\n cleaned = true\n stdin.removeListener('data', onData)\n if (stdin.setRawMode) stdin.setRawMode(false)\n if ('pause' in stdin && typeof (stdin as any).pause === 'function') {\n (stdin as any).pause()\n }\n stdout.write(ANSI.SHOW_CURSOR)\n process.removeListener('exit', cleanup)\n }\n\n function onData(data: Buffer) {\n const key = parseKey(data)\n if (key.type === 'ctrlc') {\n cleanup()\n process.exit(130)\n }\n keyHandler(key)\n }\n\n const keyHandler = handler((value: T) => {\n cleanup()\n resolve(value)\n })\n\n // Safety: restore terminal on unexpected exit\n process.on('exit', cleanup)\n\n try {\n if (stdin.setRawMode) stdin.setRawMode(true)\n stdout.write(ANSI.HIDE_CURSOR)\n stdin.on('data', onData)\n if ('resume' in stdin && typeof (stdin as any).resume === 'function') {\n (stdin as any).resume()\n }\n } catch (err) {\n cleanup()\n reject(err)\n }\n })\n}\n\n// ─── Public API ──────────────────────────────────────────────────────\n\nexport async function selectPrompt<T>(config: SelectConfig<T>): Promise<T | null> {\n const { message, options, defaultIndex = 0, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let cursorIndex = defaultIndex\n let prevLineCount = 0\n\n function draw() {\n const { text, lineCount } = renderSelect(options, cursorIndex, message)\n // Move up to overwrite previous render\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n // Clear and write each line\n const lines = text.split('\\n')\n for (const line of lines) {\n streams.stdout.write(ANSI.CLEAR_LINE + line + '\\n')\n }\n prevLineCount = lineCount\n }\n\n draw()\n\n const result = await withRawMode<T | null>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'up':\n cursorIndex = (cursorIndex - 1 + options.length) % options.length\n draw()\n break\n case 'down':\n cursorIndex = (cursorIndex + 1) % options.length\n draw()\n break\n case 'enter':\n resolve(options[cursorIndex].value)\n break\n case 'escape':\n resolve(null)\n break\n }\n }\n })\n\n // Show confirmed selection\n if (result !== null) {\n const selected = options.find((o) => o.value === result)\n if (selected) {\n // Overwrite prompt with confirmed value\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n for (let i = 0; i < prevLineCount; i++) {\n streams.stdout.write(ANSI.CLEAR_LINE + '\\n')\n }\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET} ${ANSI.CYAN}${selected.label}${ANSI.RESET}\\n`)\n }\n }\n\n return result\n}\n\nexport async function multiSelectPrompt<T>(config: MultiSelectConfig<T>): Promise<T[] | null> {\n const { message, options, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let cursorIndex = 0\n const selected = new Set<number>()\n let prevLineCount = 0\n\n // Pre-fill defaults\n for (let i = 0; i < options.length; i++) {\n if (options[i].default) selected.add(i)\n }\n\n function draw() {\n const { text, lineCount } = renderMultiSelect(options, cursorIndex, selected, message)\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n const lines = text.split('\\n')\n for (const line of lines) {\n streams.stdout.write(ANSI.CLEAR_LINE + line + '\\n')\n }\n prevLineCount = lineCount\n }\n\n draw()\n\n const result = await withRawMode<T[] | null>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'up':\n cursorIndex = (cursorIndex - 1 + options.length) % options.length\n draw()\n break\n case 'down':\n cursorIndex = (cursorIndex + 1) % options.length\n draw()\n break\n case 'space':\n if (selected.has(cursorIndex)) {\n selected.delete(cursorIndex)\n } else {\n selected.add(cursorIndex)\n }\n draw()\n break\n case 'enter':\n if (selected.size > 0) {\n const values = [...selected].sort().map((i) => options[i].value)\n resolve(values)\n }\n // If nothing selected, ignore Enter (must select at least 1)\n break\n case 'escape':\n resolve(null)\n break\n }\n }\n })\n\n // Show confirmed selection\n if (result !== null) {\n const labels = [...selected].sort().map((i) => options[i].label)\n if (prevLineCount > 0) {\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n }\n for (let i = 0; i < prevLineCount; i++) {\n streams.stdout.write(ANSI.CLEAR_LINE + '\\n')\n }\n streams.stdout.write(ANSI.moveUp(prevLineCount))\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET} ${ANSI.CYAN}${labels.join(', ')}${ANSI.RESET}\\n`)\n }\n\n return result\n}\n\n// ─── Password prompt ─────────────────────────────────────────────────\n\ninterface PasswordConfig {\n message: string\n _streams?: Streams\n}\n\nexport async function passwordPrompt(config: PasswordConfig): Promise<string> {\n const { message, _streams } = config\n const streams = _streams ?? { stdin: process.stdin, stdout: process.stdout }\n let password = ''\n\n streams.stdout.write(` ${ANSI.BOLD}${message}${ANSI.RESET}: `)\n\n const result = await withRawMode<string>(streams, (resolve) => {\n return (key: KeyPress) => {\n switch (key.type) {\n case 'char':\n password += (key as { type: 'char'; char: string }).char\n streams.stdout.write('*')\n break\n case 'space':\n password += ' '\n streams.stdout.write('*')\n break\n case 'backspace':\n if (password.length > 0) {\n password = password.slice(0, -1)\n streams.stdout.write('\\b \\b')\n }\n break\n case 'enter':\n streams.stdout.write('\\n')\n resolve(password)\n break\n case 'escape':\n streams.stdout.write('\\n')\n resolve('')\n break\n }\n }\n })\n\n return result\n}\n","import { createInterface } from 'node:readline/promises'\nimport { stdin, stdout } from 'node:process'\nimport { signIn, signUp, authenticateAndGetKey } from '../auth/supabase.js'\nimport { saveConfig, ensureDirectories, loadConfig } from '../config/loader.js'\nimport { DEFAULTS } from '../config/schema.js'\nimport { printBanner } from '../version.js'\nimport { selectPrompt, passwordPrompt } from '../ui/prompts.js'\nimport type { AuthError } from '../auth/supabase.js'\n\nexport async function loginCommand(): Promise<void> {\n printBanner()\n\n // Check if already logged in\n try {\n const config = loadConfig()\n if (config.apiKey && config.apiKey.startsWith('fmcp_')) {\n console.log(' Already logged in.')\n console.log(' Run \\x1b[1mliminal logout\\x1b[0m first to switch accounts.')\n return\n }\n } catch {\n // No config yet — proceed with login\n }\n\n await runAuthFlow()\n}\n\n/**\n * Shared auth flow used by both `liminal login` and `liminal init`.\n * Returns the API key on success.\n */\nexport async function runAuthFlow(): Promise<string> {\n const modeResult = await selectPrompt<'login' | 'signup'>({\n message: 'Welcome to Liminal',\n options: [\n { label: 'Log in', value: 'login', description: 'I have an account' },\n { label: 'Create account', value: 'signup', description: 'New to Liminal' },\n ],\n defaultIndex: 0,\n })\n const mode = modeResult ?? 'login'\n\n console.log()\n\n // Collect credentials\n const rl = createInterface({ input: stdin, output: stdout })\n let name = ''\n let email: string\n\n try {\n if (mode === 'signup') {\n name = (await rl.question(' \\x1b[1mName\\x1b[0m: ')).trim()\n if (!name) {\n console.error('\\n Error: Name is required.')\n process.exit(1)\n }\n }\n\n email = (await rl.question(' \\x1b[1mEmail\\x1b[0m: ')).trim()\n if (!email) {\n console.error('\\n Error: Email is required.')\n process.exit(1)\n }\n } finally {\n rl.close()\n }\n\n // Password (masked)\n const password = await passwordPrompt({ message: 'Password' })\n if (!password) {\n console.error('\\n Error: Password is required.')\n process.exit(1)\n }\n\n console.log()\n\n // Authenticate\n const action = mode === 'signup' ? 'Creating account' : 'Logging in'\n process.stdout.write(` ${action}... `)\n\n try {\n const auth = mode === 'signup'\n ? await signUp(email, password, name)\n : await signIn(email, password)\n\n console.log('OK')\n\n // Fetch or create API key\n process.stdout.write(' Setting up API key... ')\n const apiKey = await authenticateAndGetKey(auth)\n console.log('OK')\n\n // Save to config\n ensureDirectories()\n saveConfig({\n apiKey,\n apiBaseUrl: DEFAULTS.apiBaseUrl,\n })\n\n console.log()\n console.log(` Logged in as \\x1b[1m${auth.email}\\x1b[0m`)\n\n return apiKey\n } catch (err) {\n console.log('FAILED')\n const authErr = err as AuthError\n console.error(`\\n ${authErr.message}`)\n\n if (mode === 'login' && authErr.message?.includes('Invalid login')) {\n console.error(' Check your email and password, then try again.')\n }\n\n process.exit(1)\n }\n}\n","/**\n * Lightweight Supabase Auth client using fetch — zero npm dependencies.\n * Uses the public anon key (same as web frontend).\n */\nimport { randomBytes } from 'node:crypto'\n\nconst SUPABASE_URL = 'https://nzcneiyymvgxvttbenhp.supabase.co'\nconst SUPABASE_ANON_KEY =\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im56Y25laXl5bXZneHZ0dGJlbmhwIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQwNjQ0MjcsImV4cCI6MjA2OTY0MDQyN30.x3E-zGRadbPMmxRqT_PB_KOi00htKpgeb8GiQa4g2z0'\n\n// ─── Types ───────────────────────────────────────────────────────────\n\nexport interface AuthResult {\n accessToken: string\n userId: string\n email: string\n}\n\nexport interface AuthError {\n message: string\n status?: number\n}\n\n// ─── Auth ────────────────────────────────────────────────────────────\n\nfunction supabaseHeaders(accessToken?: string): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_ANON_KEY,\n }\n if (accessToken) {\n headers['Authorization'] = `Bearer ${accessToken}`\n }\n return headers\n}\n\n/**\n * Sign in with email and password.\n */\nexport async function signIn(email: string, password: string): Promise<AuthResult> {\n const res = await fetch(`${SUPABASE_URL}/auth/v1/token?grant_type=password`, {\n method: 'POST',\n headers: supabaseHeaders(),\n body: JSON.stringify({ email, password }),\n })\n\n const body = (await res.json()) as Record<string, any>\n\n if (!res.ok) {\n const msg = body?.error_description || body?.error || body?.msg || 'Authentication failed'\n const err: AuthError = { message: msg, status: res.status }\n throw err\n }\n\n return {\n accessToken: body.access_token,\n userId: body.user?.id,\n email: body.user?.email ?? email,\n }\n}\n\n/**\n * Sign up with email, password, and name.\n */\nexport async function signUp(\n email: string,\n password: string,\n name: string,\n): Promise<AuthResult> {\n const res = await fetch(`${SUPABASE_URL}/auth/v1/signup`, {\n method: 'POST',\n headers: supabaseHeaders(),\n body: JSON.stringify({\n email,\n password,\n data: { name },\n }),\n })\n\n const body = (await res.json()) as Record<string, any>\n\n if (!res.ok) {\n const msg = body?.error_description || body?.error || body?.msg || 'Sign up failed'\n const err: AuthError = { message: msg, status: res.status }\n throw err\n }\n\n // Supabase may return identities: [] if email confirmation is required\n if (body.user?.identities?.length === 0) {\n const err: AuthError = { message: 'Account already exists. Try logging in instead.' }\n throw err\n }\n\n return {\n accessToken: body.access_token,\n userId: body.user?.id,\n email: body.user?.email ?? email,\n }\n}\n\n// ─── API Key Management ──────────────────────────────────────────────\n\n/**\n * Fetch existing active API key for the authenticated user.\n */\nexport async function fetchApiKey(accessToken: string, userId: string): Promise<string | null> {\n const params = new URLSearchParams({\n user_id: `eq.${userId}`,\n is_active: 'eq.true',\n select: 'api_key',\n limit: '1',\n })\n\n const res = await fetch(`${SUPABASE_URL}/rest/v1/user_api_keys?${params}`, {\n headers: supabaseHeaders(accessToken),\n })\n\n if (!res.ok) return null\n\n const rows = await res.json()\n if (Array.isArray(rows) && rows.length > 0 && rows[0].api_key) {\n return rows[0].api_key as string\n }\n\n return null\n}\n\n/**\n * Generate and insert a new API key for the authenticated user.\n */\nexport async function createApiKey(accessToken: string, userId: string): Promise<string> {\n const apiKey = `fmcp_${randomBytes(32).toString('hex')}`\n\n const res = await fetch(`${SUPABASE_URL}/rest/v1/user_api_keys`, {\n method: 'POST',\n headers: {\n ...supabaseHeaders(accessToken),\n 'Prefer': 'return=representation',\n },\n body: JSON.stringify({\n user_id: userId,\n key_name: 'Liminal CLI',\n api_key: apiKey,\n is_active: true,\n }),\n })\n\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as Record<string, any>\n const msg = body?.message || body?.error || 'Failed to create API key'\n throw { message: msg, status: res.status } as AuthError\n }\n\n return apiKey\n}\n\n/**\n * Full login flow: authenticate then fetch or create API key.\n */\nexport async function authenticateAndGetKey(\n auth: AuthResult,\n): Promise<string> {\n // Try to fetch existing key first\n const existingKey = await fetchApiKey(auth.accessToken, auth.userId)\n if (existingKey) return existingKey\n\n // No key found — create one\n return createApiKey(auth.accessToken, auth.userId)\n}\n","/**\n * Claude Code connector.\n *\n * Claude Code reads the ANTHROPIC_BASE_URL environment variable to determine\n * where to send API requests. Setting this to Liminal's proxy address routes\n * all traffic through the compression pipeline.\n *\n * Protocol: Anthropic Messages API (POST /v1/messages)\n * Auth: x-api-key header (user's Anthropic API key)\n * Setup: Shell profile export — fully automatic\n */\n\nimport { execSync } from 'node:child_process'\nimport type { Connector, ConnectorInfo, ConnectorStatus, SetupResult, TeardownResult } from './types.js'\n\nconst ENV_VAR = 'ANTHROPIC_BASE_URL'\n\nconst INFO: ConnectorInfo = {\n id: 'claude-code',\n label: 'Claude Code',\n description: 'Anthropic CLI for coding with Claude',\n protocol: 'anthropic-messages',\n automatable: true,\n}\n\nfunction isClaudeInstalled(): boolean {\n try {\n execSync('which claude', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nfunction getCurrentBaseUrl(): string | undefined {\n return process.env[ENV_VAR] || undefined\n}\n\nexport const claudeCodeConnector: Connector = {\n info: INFO,\n\n async detect(): Promise<ConnectorStatus> {\n const installed = isClaudeInstalled()\n const currentUrl = getCurrentBaseUrl()\n const configured = currentUrl?.includes('127.0.0.1') ?? false\n\n if (!installed) {\n return { installed, configured: false, detail: 'Claude Code not found in PATH' }\n }\n\n if (configured) {\n return { installed, configured, detail: `Routing through ${currentUrl}` }\n }\n\n return { installed, configured, detail: 'Installed but not routing through Liminal' }\n },\n\n getShellExports(port: number): string[] {\n return [`export ${ENV_VAR}=http://127.0.0.1:${port}`]\n },\n\n async setup(port: number): Promise<SetupResult> {\n const exports = this.getShellExports(port)\n\n return {\n success: true,\n shellExports: exports,\n postSetupInstructions: [\n 'Claude Code will automatically route through Liminal.',\n 'Make sure to source your shell profile or restart your terminal.',\n ],\n }\n },\n\n async teardown(): Promise<TeardownResult> {\n return {\n success: true,\n manualSteps: [\n `Remove the line \\`export ${ENV_VAR}=...\\` from your shell profile (~/.zshrc or ~/.bashrc).`,\n 'Restart your terminal or run: unset ANTHROPIC_BASE_URL',\n ],\n }\n },\n}\n","/**\n * OpenAI Codex CLI connector.\n *\n * Codex CLI reads OPENAI_BASE_URL to override its API endpoint. It can also\n * be configured via ~/.codex/config.toml with a custom provider block.\n *\n * Protocol: OpenAI Responses API (POST /v1/responses) — this is the default\n * wire format. Chat completions is a secondary option via config.toml\n * (wire_api = \"chat_completions\") but Responses API is primary.\n * Auth: Authorization: Bearer header (user's OpenAI API key)\n * Setup: Shell profile export — fully automatic. Optional TOML config\n * for advanced users who want a named provider.\n */\n\nimport { execSync } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport type { Connector, ConnectorInfo, ConnectorStatus, SetupResult, TeardownResult } from './types.js'\n\nconst ENV_VAR = 'OPENAI_BASE_URL'\nconst CODEX_CONFIG_DIR = join(homedir(), '.codex')\nconst CODEX_CONFIG_FILE = join(CODEX_CONFIG_DIR, 'config.toml')\n\nconst INFO: ConnectorInfo = {\n id: 'codex',\n label: 'Codex CLI',\n description: 'OpenAI CLI agent for coding (Responses API)',\n protocol: 'openai-responses',\n automatable: true,\n}\n\nfunction isCodexInstalled(): boolean {\n try {\n execSync('which codex', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nfunction getCurrentBaseUrl(): string | undefined {\n return process.env[ENV_VAR] || undefined\n}\n\nfunction hasCodexConfig(): boolean {\n return existsSync(CODEX_CONFIG_FILE)\n}\n\nfunction codexConfigMentionsLiminal(): boolean {\n if (!hasCodexConfig()) return false\n try {\n const content = readFileSync(CODEX_CONFIG_FILE, 'utf-8')\n return content.includes('127.0.0.1') || content.includes('liminal')\n } catch {\n return false\n }\n}\n\nexport const codexConnector: Connector = {\n info: INFO,\n\n async detect(): Promise<ConnectorStatus> {\n const installed = isCodexInstalled()\n const currentUrl = getCurrentBaseUrl()\n const envConfigured = currentUrl?.includes('127.0.0.1') ?? false\n const tomlConfigured = codexConfigMentionsLiminal()\n const configured = envConfigured || tomlConfigured\n\n if (!installed) {\n return { installed, configured: false, detail: 'Codex CLI not found in PATH' }\n }\n\n if (configured) {\n const via = envConfigured ? ENV_VAR : 'config.toml'\n return { installed, configured, detail: `Routing through Liminal (via ${via})` }\n }\n\n return { installed, configured, detail: 'Installed but not routing through Liminal' }\n },\n\n getShellExports(port: number): string[] {\n // Codex expects base_url to include /v1\n return [`export ${ENV_VAR}=http://127.0.0.1:${port}/v1`]\n },\n\n async setup(port: number): Promise<SetupResult> {\n const exports = this.getShellExports(port)\n\n const instructions = [\n 'Codex CLI will automatically route through Liminal.',\n 'Make sure to source your shell profile or restart your terminal.',\n ]\n\n // Note about Responses API requirement\n instructions.push(\n 'Codex uses the OpenAI Responses API (/v1/responses) by default.',\n )\n\n return {\n success: true,\n shellExports: exports,\n postSetupInstructions: instructions,\n }\n },\n\n async teardown(): Promise<TeardownResult> {\n const steps = [\n `Remove the line \\`export ${ENV_VAR}=...\\` from your shell profile (~/.zshrc or ~/.bashrc).`,\n 'Restart your terminal or run: unset OPENAI_BASE_URL',\n ]\n\n if (codexConfigMentionsLiminal()) {\n steps.push(\n `Remove the Liminal provider block from ${CODEX_CONFIG_FILE}.`,\n )\n }\n\n return { success: true, manualSteps: steps }\n },\n}\n","/**\n * Cursor IDE connector.\n *\n * Cursor stores its AI settings in a SQLite database, not a plain config file.\n * It does NOT read OPENAI_BASE_URL or any env vars for its own LLM calls.\n * Configuration must be done through the Cursor Settings GUI:\n * Settings > Models > \"Override OpenAI Base URL (when using key)\"\n *\n * Protocol: OpenAI Chat Completions (POST /v1/chat/completions) for basic\n * chat, and OpenAI Responses API (POST /v1/responses) in Agent mode.\n * All requests use OpenAI wire format, even when calling Claude models.\n * Auth: Any string as API key (Liminal proxies with real auth)\n * Setup: Manual GUI configuration — cannot be fully automated.\n * The SQLite DB at ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb\n * could be written to programmatically but requires Cursor restart and\n * is fragile across Cursor updates. Guided instructions are safer.\n */\n\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport type { Connector, ConnectorInfo, ConnectorStatus, SetupResult, TeardownResult } from './types.js'\n\nconst INFO: ConnectorInfo = {\n id: 'cursor',\n label: 'Cursor',\n description: 'AI-first code editor (GUI config required)',\n protocol: 'openai-chat',\n automatable: false,\n}\n\n/** Platform-specific Cursor app paths */\nfunction getCursorPaths(): { app: string; data: string } {\n const platform = process.platform\n const home = homedir()\n\n if (platform === 'darwin') {\n return {\n app: '/Applications/Cursor.app',\n data: join(home, 'Library', 'Application Support', 'Cursor'),\n }\n }\n\n if (platform === 'win32') {\n const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming')\n const localAppData = process.env.LOCALAPPDATA || join(home, 'AppData', 'Local')\n return {\n app: join(localAppData, 'Programs', 'Cursor', 'Cursor.exe'),\n data: join(appData, 'Cursor'),\n }\n }\n\n // Linux\n return {\n app: '/usr/bin/cursor',\n data: join(home, '.config', 'Cursor'),\n }\n}\n\nfunction isCursorInstalled(): boolean {\n const { app, data } = getCursorPaths()\n return existsSync(app) || existsSync(data)\n}\n\nfunction getSettingsDbPath(): string {\n const { data } = getCursorPaths()\n return join(data, 'User', 'globalStorage', 'state.vscdb')\n}\n\nexport const cursorConnector: Connector = {\n info: INFO,\n\n async detect(): Promise<ConnectorStatus> {\n const installed = isCursorInstalled()\n const dbExists = existsSync(getSettingsDbPath())\n\n if (!installed) {\n return { installed, configured: false, detail: 'Cursor not found on this system' }\n }\n\n // We can't reliably check if Cursor is configured to use Liminal\n // without reading the SQLite DB, which requires a sqlite3 dependency.\n // Report as installed but unknown configuration state.\n return {\n installed,\n configured: false,\n detail: dbExists\n ? 'Installed — configuration requires Cursor Settings GUI'\n : 'Installed but settings database not found',\n }\n },\n\n getShellExports(_port: number): string[] {\n // Cursor does not read env vars for its LLM base URL\n return []\n },\n\n async setup(port: number): Promise<SetupResult> {\n const baseUrl = `http://127.0.0.1:${port}/v1`\n\n return {\n success: true,\n shellExports: [], // No env vars — GUI only\n postSetupInstructions: [\n 'Cursor requires manual configuration:',\n '',\n ' 1. Open Cursor Settings (not VS Code settings)',\n ' 2. Go to Models',\n ' 3. Enable \"Override OpenAI Base URL (when using key)\"',\n ` 4. Set the base URL to: ${baseUrl}`,\n ' 5. Enter any string as the API key (e.g., \"liminal\")',\n ' 6. Restart Cursor',\n '',\n 'Cursor uses OpenAI format for all models, including Claude.',\n 'Both Chat Completions and Agent mode (Responses API) are supported.',\n ],\n }\n },\n\n async teardown(): Promise<TeardownResult> {\n return {\n success: true,\n manualSteps: [\n 'In Cursor Settings > Models:',\n ' 1. Disable \"Override OpenAI Base URL (when using key)\"',\n ' 2. Clear the base URL field',\n ' 3. Restart Cursor',\n ],\n }\n },\n}\n","/**\n * Generic OpenAI-compatible connector.\n *\n * Catch-all for any tool that speaks the OpenAI API format and reads\n * OPENAI_BASE_URL or OPENAI_API_BASE. This covers tools like:\n * - Aider, Continue, Cline, Copilot alternatives\n * - Custom scripts using the OpenAI SDK\n * - Any tool that respects OPENAI_BASE_URL\n *\n * Protocol: OpenAI Chat Completions (POST /v1/chat/completions)\n * Auth: Authorization: Bearer header\n * Setup: Shell profile export — fully automatic\n */\n\nimport type { Connector, ConnectorInfo, ConnectorStatus, SetupResult, TeardownResult } from './types.js'\n\nconst ENV_VAR = 'OPENAI_BASE_URL'\n\nconst INFO: ConnectorInfo = {\n id: 'openai-compatible',\n label: 'Other / OpenAI-compatible',\n description: 'Any tool that reads OPENAI_BASE_URL',\n protocol: 'openai-chat',\n automatable: true,\n}\n\nfunction getCurrentBaseUrl(): string | undefined {\n return process.env[ENV_VAR] || undefined\n}\n\nexport const openaiCompatibleConnector: Connector = {\n info: INFO,\n\n async detect(): Promise<ConnectorStatus> {\n const currentUrl = getCurrentBaseUrl()\n const configured = currentUrl?.includes('127.0.0.1') ?? false\n\n return {\n installed: true, // Generic — always \"available\"\n configured,\n detail: configured\n ? `OPENAI_BASE_URL → ${currentUrl}`\n : 'OPENAI_BASE_URL not set to Liminal',\n }\n },\n\n getShellExports(port: number): string[] {\n return [`export ${ENV_VAR}=http://127.0.0.1:${port}/v1`]\n },\n\n async setup(port: number): Promise<SetupResult> {\n const exports = this.getShellExports(port)\n\n return {\n success: true,\n shellExports: exports,\n postSetupInstructions: [\n 'Any tool that reads OPENAI_BASE_URL will route through Liminal.',\n 'Make sure to source your shell profile or restart your terminal.',\n '',\n 'If your tool uses a different env var (e.g., OPENAI_API_BASE),',\n `set it to: http://127.0.0.1:${port}/v1`,\n ],\n }\n },\n\n async teardown(): Promise<TeardownResult> {\n return {\n success: true,\n manualSteps: [\n `Remove the line \\`export ${ENV_VAR}=...\\` from your shell profile (~/.zshrc or ~/.bashrc).`,\n 'Restart your terminal or run: unset OPENAI_BASE_URL',\n ],\n }\n },\n}\n","/**\n * Connector registry — maps tool IDs to their connector implementations.\n */\n\nimport { claudeCodeConnector } from './claude-code.js'\nimport { codexConnector } from './codex.js'\nimport { cursorConnector } from './cursor.js'\nimport { openaiCompatibleConnector } from './openai-compatible.js'\nimport type { Connector, ConnectorId } from './types.js'\n\n/** All registered connectors in display order */\nexport const CONNECTORS: readonly Connector[] = [\n claudeCodeConnector,\n codexConnector,\n cursorConnector,\n openaiCompatibleConnector,\n]\n\n/** Lookup a connector by its tool ID */\nexport function getConnector(id: ConnectorId): Connector {\n const connector = CONNECTORS.find((c) => c.info.id === id)\n if (!connector) {\n throw new Error(`Unknown connector: ${id}`)\n }\n return connector\n}\n\n/** Get connectors for a list of tool IDs */\nexport function getConnectors(ids: ConnectorId[]): Connector[] {\n return ids.map(getConnector)\n}\n\n/** Detect which tools are installed on this system */\nexport async function detectInstalledTools(): Promise<Map<ConnectorId, Connector>> {\n const results = await Promise.all(\n CONNECTORS.map(async (c) => {\n const status = await c.detect()\n return { connector: c, status }\n }),\n )\n\n const installed = new Map<ConnectorId, Connector>()\n for (const { connector, status } of results) {\n if (status.installed) {\n installed.set(connector.info.id, connector)\n }\n }\n\n return installed\n}\n\n// Re-export types for convenience\nexport type { Connector, ConnectorId, ConnectorInfo, ConnectorStatus, SetupResult, TeardownResult } from './types.js'\n","import { saveConfig, ensureDirectories } from '../config/loader.js'\nimport { DEFAULTS } from '../config/schema.js'\nimport { CONFIG_FILE } from '../config/paths.js'\nimport {\n detectShellProfile,\n appendToShellProfile,\n lineExistsInFile,\n} from '../config/shell.js'\nimport { printBanner } from '../version.js'\nimport { multiSelectPrompt, selectPrompt } from '../ui/prompts.js'\nimport { runAuthFlow } from './login.js'\nimport { CONNECTORS, getConnectors } from '../connectors/index.js'\nimport type { ConnectorId } from '../connectors/types.js'\nimport type { Tool } from '../types.js'\n\n// ─── ANSI helpers ────────────────────────────────────────────────────\nconst BOLD = '\\x1b[1m'\nconst DIM = '\\x1b[2m'\nconst CYAN = '\\x1b[36m'\nconst GREEN = '\\x1b[32m'\nconst YELLOW = '\\x1b[33m'\nconst RESET = '\\x1b[0m'\n\nexport async function initCommand(): Promise<void> {\n printBanner()\n console.log(' Welcome to Liminal -- Your Transparency & Context Partner')\n console.log()\n console.log(\" Let's start evolving.\")\n console.log()\n\n // ── 1. Authenticate ───────────────────────────────────────────\n const apiKey = await runAuthFlow()\n console.log()\n\n // ── 2. Port (use default, configurable via `liminal config --set port=XXXX`) ──\n const port = DEFAULTS.port\n\n // ── 3. Tool detection ─────────────────────────────────────────\n console.log(` ${BOLD}Detecting installed tools...${RESET}`)\n console.log()\n const detectionResults = await Promise.all(\n CONNECTORS.map(async (c) => {\n const status = await c.detect()\n return { connector: c, status }\n }),\n )\n\n for (const { connector, status } of detectionResults) {\n const icon = status.installed ? `${GREEN}✓${RESET}` : `${DIM}·${RESET}`\n console.log(` ${icon} ${connector.info.label} ${DIM}${status.detail}${RESET}`)\n }\n console.log()\n\n // ── 4. Tool selection ─────────────────────────────────────────\n const toolOptions = CONNECTORS.map((c) => {\n const detected = detectionResults.find((r) => r.connector.info.id === c.info.id)\n const installed = detected?.status.installed ?? false\n\n let description = c.info.description\n if (!installed) description += ` ${DIM}(not detected)${RESET}`\n if (!c.info.automatable) description += ` ${DIM}(manual setup)${RESET}`\n\n return {\n label: c.info.label,\n value: c.info.id as ConnectorId,\n description,\n default: c.info.id === 'claude-code' && installed,\n }\n })\n\n const toolsResult = await multiSelectPrompt<ConnectorId>({\n message: 'Which AI tools will you use with Liminal?',\n options: toolOptions,\n })\n const selectedIds: ConnectorId[] = toolsResult ?? ['claude-code']\n\n console.log()\n\n // ── 5. Response learning ──────────────────────────────────────\n const learnResult = await selectPrompt<boolean>({\n message: 'Learn from LLM responses?',\n options: [\n { label: 'Yes', value: true, description: 'Improve compression over time' },\n { label: 'No', value: false, description: 'Skip response learning' },\n ],\n defaultIndex: 0,\n })\n const learnFromResponses = learnResult ?? true\n\n console.log()\n\n // ── 6. Save config ────────────────────────────────────────────\n ensureDirectories()\n saveConfig({\n apiKey,\n apiBaseUrl: DEFAULTS.apiBaseUrl,\n upstreamBaseUrl: DEFAULTS.upstreamBaseUrl,\n anthropicUpstreamUrl: DEFAULTS.anthropicUpstreamUrl,\n port,\n learnFromResponses,\n tools: selectedIds as Tool[],\n compressionThreshold: DEFAULTS.compressionThreshold,\n compressRoles: DEFAULTS.compressRoles,\n latencyBudgetMs: DEFAULTS.latencyBudgetMs,\n enabled: DEFAULTS.enabled,\n })\n\n console.log(` ${GREEN}✓${RESET} Configuration saved to ${DIM}${CONFIG_FILE}${RESET}`)\n console.log()\n\n // ── 7. Per-connector setup ────────────────────────────────────\n // Each selected tool gets its own visible setup section so the user\n // can see exactly what's being configured for every tool they chose.\n\n const connectors = getConnectors(selectedIds)\n const allShellExports: string[] = []\n const profile = detectShellProfile()\n\n console.log(` ${BOLD}Configuring ${connectors.length} tool${connectors.length > 1 ? 's' : ''}...${RESET}`)\n\n for (const connector of connectors) {\n const result = await connector.setup(port)\n const protocol = connector.info.protocol === 'anthropic-messages'\n ? 'Anthropic Messages API'\n : connector.info.protocol === 'openai-responses'\n ? 'Responses API'\n : 'Chat Completions API'\n\n console.log()\n console.log(` ${CYAN}── ${connector.info.label} ${RESET}${DIM}(${protocol})${RESET}`)\n\n if (connector.info.automatable && result.shellExports.length > 0) {\n // Automatable: show the env var(s) being set\n for (const line of result.shellExports) {\n console.log(` ${GREEN}✓${RESET} ${line}`)\n }\n allShellExports.push(...result.shellExports)\n }\n\n // Show all setup instructions for this connector\n for (const line of result.postSetupInstructions) {\n if (line === '') {\n console.log()\n } else {\n // Skip generic \"source your shell\" messages — we handle that globally below\n if (line.includes('source your shell profile') || line.includes('restart your terminal')) continue\n if (line.includes('will automatically route through Liminal')) {\n console.log(` ${DIM}${line}${RESET}`)\n } else if (line.startsWith(' ')) {\n // Indented instructions (e.g., Cursor numbered steps)\n console.log(` ${line}`)\n } else {\n console.log(` ${line}`)\n }\n }\n }\n\n // Show manual setup badge for non-automatable connectors\n if (!connector.info.automatable) {\n console.log(` ${YELLOW}⚠ Requires manual configuration (see steps above)${RESET}`)\n }\n }\n\n // ── 8. Shell auto-configuration ───────────────────────────────\n // Deduplicate (codex + openai-compatible both set OPENAI_BASE_URL)\n const uniqueExports = [...new Set(allShellExports)]\n\n if (uniqueExports.length > 0 && profile) {\n const allExist = uniqueExports.every((line) => lineExistsInFile(profile.path, line))\n\n console.log()\n if (allExist) {\n console.log(` ${GREEN}✓${RESET} Shell already configured in ${profile.name}`)\n } else {\n const autoResult = await selectPrompt<boolean>({\n message: `Add proxy exports to ${profile.name}?`,\n options: [\n { label: 'Yes', value: true, description: 'Automatic shell configuration' },\n { label: 'No', value: false, description: \"I'll set it up manually\" },\n ],\n defaultIndex: 0,\n })\n\n if (autoResult === true) {\n const added = appendToShellProfile(profile, uniqueExports)\n if (added.length > 0) {\n console.log()\n console.log(` ${GREEN}✓${RESET} Added to ${profile.name}`)\n console.log()\n console.log(` Run ${BOLD}source ${profile.name}${RESET} or restart your terminal.`)\n }\n } else {\n console.log()\n console.log(' Add these to your shell profile:')\n console.log()\n for (const line of uniqueExports) {\n console.log(` ${CYAN}${line}${RESET}`)\n }\n }\n }\n } else if (uniqueExports.length > 0) {\n // No shell profile detected\n console.log()\n console.log(' Add these to your shell profile:')\n console.log()\n for (const line of uniqueExports) {\n console.log(` ${CYAN}${line}${RESET}`)\n }\n }\n\n // ── 9. Done ───────────────────────────────────────────────────\n console.log()\n console.log(` ${BOLD}Setup complete!${RESET}`)\n console.log()\n console.log(' Next step:')\n console.log(` ${BOLD}liminal start${RESET}`)\n console.log()\n}\n","import { saveConfig, isConfigured } from '../config/loader.js'\n\nexport async function logoutCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log(' Not currently logged in.')\n return\n }\n\n saveConfig({ apiKey: '' })\n console.log(' Logged out.')\n console.log(' Run \\x1b[1mliminal login\\x1b[0m to reconnect.')\n}\n","import {\n CompressionPipeline,\n RSCTransport,\n RSCEventEmitter,\n Session,\n CircuitBreaker,\n} from '@cognisos/rsc-sdk'\nimport type { SessionSummary, CircuitState } from '@cognisos/rsc-sdk'\n\nexport interface PipelineConfig {\n rscApiKey: string\n rscBaseUrl: string\n compressionThreshold: number\n learnFromResponses: boolean\n latencyBudgetMs?: number\n sessionId?: string\n}\n\nexport class RSCPipelineWrapper {\n readonly pipeline: CompressionPipeline\n readonly session: Session\n readonly events: RSCEventEmitter\n readonly transport: RSCTransport\n private readonly circuitBreaker: CircuitBreaker\n\n constructor(config: PipelineConfig) {\n this.circuitBreaker = new CircuitBreaker(5, 5 * 60 * 1000)\n\n this.transport = new RSCTransport({\n baseUrl: config.rscBaseUrl,\n apiKey: config.rscApiKey,\n timeout: 30_000,\n maxRetries: 3,\n circuitBreaker: this.circuitBreaker,\n })\n\n this.events = new RSCEventEmitter()\n this.session = new Session(config.sessionId)\n\n this.pipeline = new CompressionPipeline(\n this.transport,\n {\n threshold: config.compressionThreshold,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs,\n sessionId: this.session.sessionId,\n },\n this.events,\n )\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n await this.transport.get<{ status: string }>('/health')\n return true\n } catch {\n return false\n }\n }\n\n getSessionSummary(): SessionSummary {\n return this.session.getSummary()\n }\n\n getCircuitState(): CircuitState {\n return this.circuitBreaker.getState()\n }\n\n isCircuitOpen(): boolean {\n return this.circuitBreaker.getState() === 'open'\n }\n\n resetCircuitBreaker(): void {\n this.circuitBreaker.reset()\n }\n}\n","import * as http from 'node:http'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport { compressMessages } from '../rsc/message-compressor.js'\nimport { createStreamLearningBuffer } from '../rsc/learning.js'\nimport { pipeSSEResponse } from './streaming.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ChatCompletionRequest, ResolvedConfig } from '../types.js'\nimport type { Logger } from './handler.js'\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')\n}\n\nfunction sendJSON(res: http.ServerResponse, status: number, body: unknown): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\n/**\n * Extract the bearer token from the Authorization header.\n * This is the user's LLM API key — used to forward to the upstream LLM.\n */\nfunction extractBearerToken(req: http.IncomingMessage): string | null {\n const auth = req.headers.authorization\n if (!auth || !auth.startsWith('Bearer ')) return null\n return auth.slice(7)\n}\n\nexport async function handleChatCompletions(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const request = body as ChatCompletionRequest\n\n // Validate required fields\n if (!request.messages || !Array.isArray(request.messages)) {\n sendJSON(res, 400, {\n error: { message: 'messages is required and must be an array', type: 'invalid_request_error' },\n })\n return\n }\n\n // Extract LLM API key from the incoming request\n const llmApiKey = extractBearerToken(req)\n if (!llmApiKey) {\n sendJSON(res, 401, {\n error: { message: 'Authorization header with Bearer token is required', type: 'authentication_error' },\n })\n return\n }\n\n // Compress messages (or passthrough if circuit is open / disabled)\n let messages = request.messages\n let anyCompressed = false\n let totalTokensSaved = 0\n\n if (config.enabled && !pipeline.isCircuitOpen()) {\n try {\n const compressRoles = new Set(config.compressRoles)\n const result = await compressMessages(\n request.messages,\n pipeline.pipeline,\n pipeline.session,\n compressRoles,\n )\n messages = result.messages\n anyCompressed = result.anyCompressed\n totalTokensSaved = result.totalTokensSaved\n\n if (result.totalTokensSaved > 0) {\n logger.log(`[COMPRESS] Saved ${result.totalTokensSaved} tokens`)\n }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n logger.log('[DEGRADE] Circuit breaker open — passing through directly')\n } else {\n logger.log(`[ERROR] Compression failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n // Fall through with original messages\n messages = request.messages\n }\n }\n\n // Build upstream request\n const upstreamUrl = `${config.upstreamBaseUrl}/v1/chat/completions`\n const upstreamBody = { ...request, messages }\n\n const upstreamHeaders: Record<string, string> = {\n 'Authorization': `Bearer ${llmApiKey}`,\n 'Content-Type': 'application/json',\n }\n\n // Forward streaming preference\n if (request.stream) {\n upstreamHeaders['Accept'] = 'text/event-stream'\n }\n\n try {\n const upstreamResponse = await fetch(upstreamUrl, {\n method: 'POST',\n headers: upstreamHeaders,\n body: JSON.stringify(upstreamBody),\n })\n\n // Handle upstream errors\n if (!upstreamResponse.ok) {\n const errorBody = await upstreamResponse.text()\n setCORSHeaders(res)\n res.writeHead(upstreamResponse.status, {\n 'Content-Type': upstreamResponse.headers.get('Content-Type') || 'application/json',\n })\n res.end(errorBody)\n return\n }\n\n // Streaming response\n if (request.stream && upstreamResponse.body) {\n const learningBuffer = anyCompressed\n ? createStreamLearningBuffer(pipeline.pipeline)\n : null\n\n await pipeSSEResponse(\n upstreamResponse,\n res,\n (text) => learningBuffer?.append(text),\n () => learningBuffer?.flush(),\n totalTokensSaved,\n )\n return\n }\n\n // Non-streaming response\n const responseBody = await upstreamResponse.text()\n\n // Adjust usage to reflect pre-compression token count\n let finalBody = responseBody\n if (totalTokensSaved > 0) {\n try {\n const parsed = JSON.parse(responseBody)\n if (parsed?.usage?.prompt_tokens != null) {\n parsed.usage.prompt_tokens += totalTokensSaved\n if (parsed.usage.total_tokens != null) {\n parsed.usage.total_tokens += totalTokensSaved\n }\n finalBody = JSON.stringify(parsed)\n logger.log(`[TOKENS] Adjusted prompt_tokens by +${totalTokensSaved}`)\n }\n } catch {\n // Pass through unmodified on parse error\n }\n }\n\n setCORSHeaders(res)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(finalBody)\n\n // Trigger learning from response (fire-and-forget, uses original body)\n if (anyCompressed) {\n try {\n const parsed = JSON.parse(responseBody)\n const content = parsed?.choices?.[0]?.message?.content\n if (typeof content === 'string' && content.length > 0) {\n pipeline.pipeline.triggerLearning(content)\n }\n } catch {\n // Ignore learning parse errors\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Upstream request failed: ${message}`)\n if (!res.headersSent) {\n sendJSON(res, 502, {\n error: { message: `Failed to reach upstream LLM: ${message}`, type: 'server_error' },\n })\n }\n }\n}\n","import type { CompressionPipeline, Session } from '@cognisos/rsc-sdk'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport type { ChatCompletionMessage, ContentPart } from '../types.js'\nimport { segmentContent } from './content-segmenter.js'\n\nexport interface CompressedMessagesResult {\n messages: ChatCompletionMessage[]\n anyCompressed: boolean\n totalTokensSaved: number\n}\n\n/**\n * Walk an array of ChatCompletion messages and compress eligible ones\n * via the RSC CompressionPipeline. Non-eligible roles and non-text\n * content parts pass through unchanged.\n */\nexport async function compressMessages(\n messages: ChatCompletionMessage[],\n pipeline: CompressionPipeline,\n session: Session,\n compressRoles: Set<string>,\n): Promise<CompressedMessagesResult> {\n let anyCompressed = false\n let totalTokensSaved = 0\n\n const compressed = await Promise.all(\n messages.map(async (msg) => {\n if (!compressRoles.has(msg.role)) return msg\n\n // String content\n if (typeof msg.content === 'string') {\n return compressStringContent(msg, pipeline, session, (c, saved) => {\n anyCompressed = anyCompressed || c\n totalTokensSaved += saved\n })\n }\n\n // Array content (vision messages with text + image parts)\n if (Array.isArray(msg.content)) {\n return compressArrayContent(msg, pipeline, session, (c, saved) => {\n anyCompressed = anyCompressed || c\n totalTokensSaved += saved\n })\n }\n\n // null or other content — pass through\n return msg\n }),\n )\n\n return { messages: compressed, anyCompressed, totalTokensSaved }\n}\n\nasync function compressStringContent(\n msg: ChatCompletionMessage,\n pipeline: CompressionPipeline,\n session: Session,\n record: (compressed: boolean, saved: number) => void,\n): Promise<ChatCompletionMessage> {\n const text = msg.content as string\n const segments = segmentContent(text)\n const hasCode = segments.some(s => s.type === 'code')\n\n // Fast path: no code detected — compress the whole string as before\n if (!hasCode) {\n try {\n const result = await pipeline.compressForLLM(text)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return { ...msg, content: result.text }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n session.recordFailure()\n throw err\n }\n session.recordFailure()\n return msg\n }\n }\n\n // Segment-aware: compress prose, pass code through verbatim\n try {\n const parts = await Promise.all(\n segments.map(async (seg) => {\n if (seg.type === 'code') return seg.text\n if (seg.text.trim().length === 0) return seg.text\n try {\n const result = await pipeline.compressForLLM(seg.text)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return result.text\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) throw err\n session.recordFailure()\n return seg.text\n }\n }),\n )\n return { ...msg, content: parts.join('') }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n session.recordFailure()\n throw err\n }\n session.recordFailure()\n return msg\n }\n}\n\nasync function compressTextWithSegmentation(\n text: string,\n pipeline: CompressionPipeline,\n session: Session,\n record: (compressed: boolean, saved: number) => void,\n): Promise<string> {\n const segments = segmentContent(text)\n const hasCode = segments.some(s => s.type === 'code')\n\n if (!hasCode) {\n const result = await pipeline.compressForLLM(text)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return result.text\n }\n\n const parts = await Promise.all(\n segments.map(async (seg) => {\n if (seg.type === 'code') return seg.text\n if (seg.text.trim().length === 0) return seg.text\n try {\n const result = await pipeline.compressForLLM(seg.text)\n session.recordCompression(result.metrics)\n record(!result.metrics.skipped, result.metrics.tokensSaved)\n return result.text\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) throw err\n session.recordFailure()\n return seg.text\n }\n }),\n )\n return parts.join('')\n}\n\nasync function compressArrayContent(\n msg: ChatCompletionMessage,\n pipeline: CompressionPipeline,\n session: Session,\n record: (compressed: boolean, saved: number) => void,\n): Promise<ChatCompletionMessage> {\n const parts = msg.content as ContentPart[]\n\n const compressedParts = await Promise.all(\n parts.map(async (part) => {\n if (part.type === 'text' && typeof part.text === 'string') {\n try {\n const compressed = await compressTextWithSegmentation(part.text, pipeline, session, record)\n return { ...part, text: compressed }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n session.recordFailure()\n throw err\n }\n session.recordFailure()\n return part\n }\n }\n // Pass through image_url, tool_use, etc.\n return part\n }),\n )\n\n return { ...msg, content: compressedParts }\n}\n","/**\n * Content segmenter — splits mixed text into code and prose segments.\n * Code segments (fenced blocks, indented blocks) pass through compression\n * unchanged to avoid destructive normalization (casefold, punct strip, lemmatize).\n */\n\nexport interface ContentSegment {\n type: 'prose' | 'code'\n text: string\n}\n\n/**\n * Segment text content into code and prose blocks.\n *\n * Detection rules:\n * 1. Fenced code blocks: ``` or ~~~ (with optional language tag) through closing fence\n * 2. Indented code blocks: 4+ space or tab-indented contiguous lines\n * 3. Everything else → prose\n *\n * Round-trip invariant: segments.map(s => s.text).join('') === input\n */\nexport function segmentContent(text: string): ContentSegment[] {\n if (text.length === 0) return [{ type: 'prose', text: '' }]\n\n const segments: ContentSegment[] = []\n const lines = text.split('\\n')\n let i = 0\n let proseBuf: string[] = []\n\n function flushProse(): void {\n if (proseBuf.length > 0) {\n segments.push({ type: 'prose', text: proseBuf.join('\\n') })\n proseBuf = []\n }\n }\n\n while (i < lines.length) {\n const line = lines[i]\n\n // Check for fenced code block opening\n const fenceMatch = matchFenceOpen(line)\n if (fenceMatch) {\n // Before flushing prose, add the newline that separated prose from this fence\n if (proseBuf.length > 0) {\n // The newline before this line belongs to the prose segment\n flushProse()\n // Add the newline separator between prose and code\n segments[segments.length - 1].text += '\\n'\n }\n\n const codeBuf: string[] = [line]\n i++\n\n // Scan until closing fence of same type and length\n let closed = false\n while (i < lines.length) {\n codeBuf.push(lines[i])\n if (matchFenceClose(lines[i], fenceMatch.char, fenceMatch.length)) {\n closed = true\n i++\n break\n }\n i++\n }\n\n // Add trailing newline if not at end of input\n let codeText = codeBuf.join('\\n')\n if (i < lines.length) {\n codeText += '\\n'\n }\n\n segments.push({ type: 'code', text: codeText })\n continue\n }\n\n // Check for indented code block (4+ spaces or tab)\n if (isIndentedCodeLine(line)) {\n if (proseBuf.length > 0) {\n flushProse()\n segments[segments.length - 1].text += '\\n'\n }\n\n const codeBuf: string[] = [line]\n i++\n\n // Consume contiguous indented lines (allow blank lines within)\n while (i < lines.length) {\n if (isIndentedCodeLine(lines[i])) {\n codeBuf.push(lines[i])\n i++\n } else if (lines[i].trim() === '' && i + 1 < lines.length && isIndentedCodeLine(lines[i + 1])) {\n // Blank line between indented lines — still part of code block\n codeBuf.push(lines[i])\n i++\n } else {\n break\n }\n }\n\n let codeText = codeBuf.join('\\n')\n if (i < lines.length) {\n codeText += '\\n'\n }\n\n segments.push({ type: 'code', text: codeText })\n continue\n }\n\n // Regular prose line\n if (proseBuf.length > 0) {\n proseBuf.push(line)\n } else {\n proseBuf.push(line)\n }\n i++\n }\n\n // Flush remaining prose\n if (proseBuf.length > 0) {\n flushProse()\n }\n\n // Ensure at least one segment\n if (segments.length === 0) {\n return [{ type: 'prose', text }]\n }\n\n return segments\n}\n\ninterface FenceInfo {\n char: string\n length: number\n}\n\nfunction matchFenceOpen(line: string): FenceInfo | null {\n // Match ``` or ~~~ with optional language tag, allowing leading whitespace (0-3 spaces)\n const match = line.match(/^( {0,3})((`{3,})|~{3,})(.*)$/)\n if (!match) return null\n\n const fenceStr = match[2]\n const char = fenceStr[0]\n\n // Backtick fences: info string must not contain backticks\n if (char === '`' && match[4] && match[4].includes('`')) return null\n\n return { char, length: fenceStr.length }\n}\n\nfunction matchFenceClose(line: string, char: string, minLength: number): boolean {\n const match = line.match(/^( {0,3})((`{3,})|(~{3,}))\\s*$/)\n if (!match) return false\n const fenceStr = match[2]\n return fenceStr[0] === char && fenceStr.length >= minLength\n}\n\nfunction isIndentedCodeLine(line: string): boolean {\n // 4+ spaces or starts with tab (and not blank)\n return (line.startsWith(' ') || line.startsWith('\\t')) && line.trim().length > 0\n}\n","import type { CompressionPipeline } from '@cognisos/rsc-sdk'\n\n/**\n * Creates a buffer that accumulates streamed response text and triggers\n * background learning when the stream completes.\n */\nexport function createStreamLearningBuffer(pipeline: CompressionPipeline) {\n let buffer = ''\n\n return {\n /** Append a text delta from an SSE chunk */\n append(text: string): void {\n buffer += text\n },\n\n /** Flush the buffer — triggers fire-and-forget learning */\n flush(): void {\n if (buffer.length > 0) {\n pipeline.triggerLearning(buffer)\n buffer = ''\n }\n },\n\n /** Get current buffer contents (for testing) */\n getBuffer(): string {\n return buffer\n },\n }\n}\n","import * as http from 'node:http'\n\n/**\n * Pipe an SSE response from an upstream LLM to the client,\n * parsing content deltas for the learning buffer.\n *\n * When totalTokensSaved > 0, intercepts the final usage chunk to adjust\n * prompt_tokens and total_tokens to reflect the pre-compression token count.\n *\n * Writes each chunk immediately — zero buffering, zero added latency\n * (except for the single usage chunk which may get rewritten).\n */\nexport async function pipeSSEResponse(\n upstreamResponse: Response,\n clientRes: http.ServerResponse,\n onContentDelta: (text: string) => void,\n onComplete: () => void,\n totalTokensSaved = 0,\n): Promise<void> {\n clientRes.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n })\n\n const reader = upstreamResponse.body!.getReader()\n const decoder = new TextDecoder()\n let lineBuf = ''\n const needsAdjustment = totalTokensSaved > 0\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n\n // Fast path: no token adjustment needed\n if (!needsAdjustment) {\n clientRes.write(chunk)\n\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const json = JSON.parse(line.slice(6))\n const content = json?.choices?.[0]?.delta?.content\n if (typeof content === 'string') {\n onContentDelta(content)\n }\n } catch {\n // Malformed SSE data — ignore for learning\n }\n }\n }\n continue\n }\n\n // Slow path: check each data line for usage to adjust\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n let adjusted = false\n const outputLines: string[] = []\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const json = JSON.parse(line.slice(6))\n\n // Check for usage in this chunk (OpenAI sends it in the final chunk)\n if (json?.usage?.prompt_tokens != null) {\n json.usage.prompt_tokens += totalTokensSaved\n if (json.usage.total_tokens != null) {\n json.usage.total_tokens += totalTokensSaved\n }\n outputLines.push(`data: ${JSON.stringify(json)}`)\n adjusted = true\n } else {\n outputLines.push(line)\n }\n\n // Learning: extract content deltas\n const content = json?.choices?.[0]?.delta?.content\n if (typeof content === 'string') {\n onContentDelta(content)\n }\n } catch {\n outputLines.push(line)\n }\n } else {\n outputLines.push(line)\n }\n }\n\n if (adjusted) {\n const reconstructed = outputLines.join('\\n') + '\\n'\n clientRes.write(reconstructed)\n } else {\n clientRes.write(chunk)\n }\n }\n } finally {\n clientRes.end()\n onComplete()\n }\n}\n","import * as http from 'node:http'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport { compressMessages } from '../rsc/message-compressor.js'\nimport { createStreamLearningBuffer } from '../rsc/learning.js'\nimport { pipeAnthropicSSEResponse } from './anthropic-streaming.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ChatCompletionMessage, ResolvedConfig } from '../types.js'\nimport type { AnthropicMessagesRequest, AnthropicMessage, AnthropicContentBlock } from '../types/anthropic.js'\nimport type { Logger } from './handler.js'\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, anthropic-beta')\n}\n\nfunction sendAnthropicError(res: http.ServerResponse, status: number, type: string, message: string): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({ type: 'error', error: { type, message } }))\n}\n\n/**\n * Extract auth headers from incoming request.\n * Supports both x-api-key (API users) and Authorization: Bearer (subscription/OAuth users).\n */\nfunction extractAuthHeaders(req: http.IncomingMessage): Record<string, string> {\n const headers: Record<string, string> = {}\n\n const xApiKey = req.headers['x-api-key']\n if (typeof xApiKey === 'string' && xApiKey.length > 0) {\n headers['x-api-key'] = xApiKey\n }\n\n const auth = req.headers['authorization']\n if (typeof auth === 'string' && auth.length > 0) {\n headers['Authorization'] = auth\n }\n\n return headers\n}\n\n/**\n * Convert Anthropic messages to ChatCompletionMessage[] for the compressor.\n * The structures are compatible — this is a thin adapter.\n */\nfunction convertAnthropicToCompressible(messages: AnthropicMessage[]): ChatCompletionMessage[] {\n return messages.map((msg) => ({\n role: msg.role,\n content: msg.content as string | AnthropicContentBlock[],\n }))\n}\n\n/**\n * Convert compressed ChatCompletionMessage[] back to Anthropic format.\n */\nfunction convertCompressedToAnthropic(messages: ChatCompletionMessage[]): AnthropicMessage[] {\n return messages.map((msg) => ({\n role: msg.role as 'user' | 'assistant',\n content: msg.content as string | AnthropicContentBlock[],\n }))\n}\n\nexport async function handleAnthropicMessages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const request = body as AnthropicMessagesRequest\n\n // Validate required fields\n if (!request.messages || !Array.isArray(request.messages)) {\n sendAnthropicError(res, 400, 'invalid_request_error', 'messages is required and must be an array')\n return\n }\n\n if (typeof request.max_tokens !== 'number') {\n sendAnthropicError(res, 400, 'invalid_request_error', 'max_tokens is required')\n return\n }\n\n // Extract auth headers (x-api-key for API users, Authorization for subscription/OAuth)\n const authHeaders = extractAuthHeaders(req)\n if (Object.keys(authHeaders).length === 0) {\n sendAnthropicError(res, 401, 'authentication_error', 'Authentication required (x-api-key or Authorization header)')\n return\n }\n\n // Compress messages (reuse existing compressor via format conversion)\n let messages = request.messages\n let anyCompressed = false\n let totalTokensSaved = 0\n\n if (config.enabled && !pipeline.isCircuitOpen()) {\n try {\n const compressRoles = new Set(config.compressRoles)\n const compressible = convertAnthropicToCompressible(request.messages)\n const result = await compressMessages(\n compressible,\n pipeline.pipeline,\n pipeline.session,\n compressRoles,\n )\n messages = convertCompressedToAnthropic(result.messages)\n anyCompressed = result.anyCompressed\n totalTokensSaved = result.totalTokensSaved\n\n if (result.totalTokensSaved > 0) {\n logger.log(`[COMPRESS] Saved ${result.totalTokensSaved} tokens`)\n }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n logger.log('[DEGRADE] Circuit breaker open -- passing through directly')\n } else {\n logger.log(`[ERROR] Compression failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n messages = request.messages\n }\n }\n\n // Build upstream request\n const upstreamUrl = `${config.anthropicUpstreamUrl}/v1/messages`\n const upstreamBody = { ...request, messages }\n\n const upstreamHeaders: Record<string, string> = {\n ...authHeaders,\n 'anthropic-version': (req.headers['anthropic-version'] as string) || '2023-06-01',\n 'Content-Type': 'application/json',\n }\n\n // Forward anthropic-beta header if present\n const betaHeader = req.headers['anthropic-beta']\n if (typeof betaHeader === 'string') {\n upstreamHeaders['anthropic-beta'] = betaHeader\n }\n\n // Log request details for debugging\n const authTypes = Object.keys(authHeaders).join(', ') || 'none'\n logger.log(`[ANTHROPIC] ${request.model} → ${upstreamUrl} (auth: ${authTypes})`)\n\n try {\n const upstreamResponse = await fetch(upstreamUrl, {\n method: 'POST',\n headers: upstreamHeaders,\n body: JSON.stringify(upstreamBody),\n })\n\n // Handle upstream errors\n if (!upstreamResponse.ok) {\n const errorBody = await upstreamResponse.text()\n logger.log(`[ANTHROPIC] Upstream error ${upstreamResponse.status}: ${errorBody.slice(0, 500)}`)\n setCORSHeaders(res)\n res.writeHead(upstreamResponse.status, {\n 'Content-Type': upstreamResponse.headers.get('Content-Type') || 'application/json',\n })\n res.end(errorBody)\n return\n }\n\n // Streaming response\n if (request.stream && upstreamResponse.body) {\n const learningBuffer = anyCompressed\n ? createStreamLearningBuffer(pipeline.pipeline)\n : null\n\n await pipeAnthropicSSEResponse(\n upstreamResponse,\n res,\n (text) => learningBuffer?.append(text),\n () => learningBuffer?.flush(),\n totalTokensSaved,\n )\n return\n }\n\n // Non-streaming response\n const responseBody = await upstreamResponse.text()\n\n // Adjust usage.input_tokens to reflect pre-compression token count\n let finalBody = responseBody\n if (totalTokensSaved > 0) {\n try {\n const parsed = JSON.parse(responseBody)\n if (parsed?.usage?.input_tokens != null) {\n parsed.usage.input_tokens += totalTokensSaved\n finalBody = JSON.stringify(parsed)\n logger.log(`[TOKENS] Adjusted input_tokens by +${totalTokensSaved}`)\n }\n } catch {\n // Pass through unmodified on parse error\n }\n }\n\n setCORSHeaders(res)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(finalBody)\n\n // Trigger learning from response (fire-and-forget, uses original body)\n if (anyCompressed) {\n try {\n const parsed = JSON.parse(responseBody)\n const textBlocks = parsed?.content?.filter(\n (b: AnthropicContentBlock) => b.type === 'text' && typeof b.text === 'string',\n )\n const content = textBlocks?.map((b: AnthropicContentBlock) => b.text).join('')\n if (typeof content === 'string' && content.length > 0) {\n pipeline.pipeline.triggerLearning(content)\n }\n } catch {\n // Ignore learning parse errors\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Upstream request failed: ${message}`)\n if (!res.headersSent) {\n sendAnthropicError(res, 502, 'api_error', `Failed to reach upstream: ${message}`)\n }\n }\n}\n","import * as http from 'node:http'\n\n/**\n * Adjust a `message_start` SSE data line to restore pre-compression input_tokens.\n * Returns the adjusted line if modified, or null if no adjustment was made.\n */\nfunction adjustMessageStartLine(dataLine: string, tokensSaved: number): string | null {\n try {\n const json = JSON.parse(dataLine.slice(6)) // strip \"data: \"\n if (json?.message?.usage?.input_tokens != null) {\n json.message.usage.input_tokens += tokensSaved\n return `data: ${JSON.stringify(json)}`\n }\n } catch {\n // Malformed JSON — don't adjust\n }\n return null\n}\n\n/**\n * Pipe an Anthropic SSE response from the upstream to the client,\n * parsing content_block_delta events for the learning buffer.\n *\n * Anthropic SSE format:\n * event: content_block_delta\n * data: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello\"}}\n *\n * When totalTokensSaved > 0, intercepts the message_start event to adjust\n * usage.input_tokens to reflect the pre-compression token count.\n *\n * Writes each chunk immediately — zero buffering, zero added latency\n * (except for the single message_start chunk which gets rewritten).\n */\nexport async function pipeAnthropicSSEResponse(\n upstreamResponse: Response,\n clientRes: http.ServerResponse,\n onContentDelta: (text: string) => void,\n onComplete: () => void,\n totalTokensSaved = 0,\n): Promise<void> {\n clientRes.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n })\n\n const reader = upstreamResponse.body!.getReader()\n const decoder = new TextDecoder()\n let lineBuf = ''\n let currentEvent = ''\n let usageAdjusted = false\n const needsAdjustment = totalTokensSaved > 0\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n\n // Fast path: if no adjustment needed (or already done), write immediately\n if (!needsAdjustment || usageAdjusted) {\n clientRes.write(chunk)\n\n // Still parse for learning\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7).trim()\n } else if (line.startsWith('data: ') && currentEvent === 'content_block_delta') {\n try {\n const json = JSON.parse(line.slice(6))\n if (json?.delta?.type === 'text_delta' && typeof json.delta.text === 'string') {\n onContentDelta(json.delta.text)\n }\n } catch {\n // Malformed data — ignore for learning\n }\n }\n }\n continue\n }\n\n // Slow path: need to check for message_start to adjust usage\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n let adjusted = false\n const outputLines: string[] = []\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7).trim()\n outputLines.push(line)\n } else if (line.startsWith('data: ') && currentEvent === 'message_start' && !usageAdjusted) {\n const adjustedLine = adjustMessageStartLine(line, totalTokensSaved)\n if (adjustedLine) {\n outputLines.push(adjustedLine)\n usageAdjusted = true\n adjusted = true\n } else {\n outputLines.push(line)\n }\n } else {\n outputLines.push(line)\n\n // Learning: extract content deltas\n if (line.startsWith('data: ') && currentEvent === 'content_block_delta') {\n try {\n const json = JSON.parse(line.slice(6))\n if (json?.delta?.type === 'text_delta' && typeof json.delta.text === 'string') {\n onContentDelta(json.delta.text)\n }\n } catch {\n // Malformed data — ignore for learning\n }\n }\n }\n }\n\n if (adjusted) {\n // Reconstruct the chunk from adjusted lines + remaining buffer\n const reconstructed = outputLines.join('\\n') + '\\n' + (lineBuf ? '' : '')\n clientRes.write(reconstructed)\n } else {\n // No adjustment made in this chunk — write original\n clientRes.write(chunk)\n }\n }\n } finally {\n clientRes.end()\n onComplete()\n }\n}\n","import * as http from 'node:http'\nimport { RSCCircuitOpenError } from '@cognisos/rsc-sdk'\nimport { compressMessages } from '../rsc/message-compressor.js'\nimport { createStreamLearningBuffer } from '../rsc/learning.js'\nimport { pipeResponsesSSE } from './responses-streaming.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ChatCompletionMessage, ResolvedConfig } from '../types.js'\nimport type { Logger } from './handler.js'\nimport type {\n ResponsesRequest,\n ResponsesInputItem,\n ResponsesMessageItem,\n ResponsesInputContent,\n ResponsesInputTextContent,\n ResponsesResponse,\n ResponsesOutputItem,\n ResponsesOutputMessage,\n} from '../types/responses.js'\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')\n}\n\nfunction sendJSON(res: http.ServerResponse, status: number, body: unknown): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\nfunction extractBearerToken(req: http.IncomingMessage): string | null {\n const auth = req.headers.authorization\n if (!auth || !auth.startsWith('Bearer ')) return null\n return auth.slice(7)\n}\n\n// ─── Input conversion ───────────────────────────────────────────────\n// Convert Responses API input items to ChatCompletionMessage[] for the\n// shared message compressor. Only message items with text content are\n// compressible — function call outputs, item references, images, and\n// files pass through unchanged.\n\nfunction isMessageItem(item: ResponsesInputItem): item is ResponsesMessageItem {\n return item.type === 'message'\n}\n\nfunction inputToCompressibleMessages(input: string | ResponsesInputItem[]): ChatCompletionMessage[] {\n // Simple string input\n if (typeof input === 'string') {\n return [{ role: 'user', content: input }]\n }\n\n const messages: ChatCompletionMessage[] = []\n\n for (const item of input) {\n if (!isMessageItem(item)) continue\n\n if (typeof item.content === 'string') {\n // Map 'developer' role → 'system' for the compressor\n const role = item.role === 'developer' ? 'system' : item.role\n messages.push({ role, content: item.content })\n } else if (Array.isArray(item.content)) {\n // Content array — extract text parts, preserve structure\n const role = item.role === 'developer' ? 'system' : item.role\n const parts = item.content.map((c: ResponsesInputContent) => {\n if (c.type === 'input_text') {\n return { type: 'text' as const, text: (c as ResponsesInputTextContent).text }\n }\n // Images and files pass through as non-text parts\n return c as unknown as { type: string; [key: string]: unknown }\n })\n messages.push({ role, content: parts })\n }\n }\n\n return messages\n}\n\n// ─── Apply compressed messages back to input ────────────────────────\n// After compression, we need to write the compressed text back into the\n// original Responses API input structure, preserving non-message items,\n// images, file references, etc.\n\nfunction applyCompressedToInput(\n originalInput: string | ResponsesInputItem[],\n compressedMessages: ChatCompletionMessage[],\n): string | ResponsesInputItem[] {\n // Simple string input — return compressed string directly\n if (typeof originalInput === 'string') {\n const first = compressedMessages[0]\n if (first && typeof first.content === 'string') {\n return first.content\n }\n return originalInput\n }\n\n // Array input — walk through and replace message items\n let msgIdx = 0\n const result: ResponsesInputItem[] = []\n\n for (const item of originalInput) {\n if (!isMessageItem(item)) {\n // Non-message items (function_call_output, item_reference, etc.) pass through\n result.push(item)\n continue\n }\n\n const compressed = compressedMessages[msgIdx]\n msgIdx++\n\n if (!compressed) {\n result.push(item)\n continue\n }\n\n if (typeof compressed.content === 'string') {\n result.push({\n ...item,\n content: compressed.content,\n } as ResponsesMessageItem)\n } else if (Array.isArray(compressed.content)) {\n // Convert back to Responses API content format\n const content: ResponsesInputContent[] = compressed.content.map((part) => {\n if (part.type === 'text' && 'text' in part) {\n return { type: 'input_text' as const, text: part.text as string }\n }\n return part as unknown as ResponsesInputContent\n })\n result.push({\n ...item,\n content,\n } as ResponsesMessageItem)\n } else {\n result.push(item)\n }\n }\n\n return result\n}\n\n// ─── Extract text from response output for learning ─────────────────\n\nfunction extractOutputText(output: ResponsesOutputItem[]): string {\n const texts: string[] = []\n for (const item of output) {\n if (item.type === 'message') {\n const msg = item as ResponsesOutputMessage\n for (const block of msg.content) {\n if (block.type === 'output_text' && typeof block.text === 'string') {\n texts.push(block.text)\n }\n }\n }\n }\n return texts.join('')\n}\n\n// ─── Main handler ───────────────────────────────────────────────────\n\nexport async function handleResponses(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: unknown,\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const request = body as ResponsesRequest\n\n // Validate required fields\n if (request.input === undefined || request.input === null) {\n sendJSON(res, 400, {\n error: { message: 'input is required', type: 'invalid_request_error' },\n })\n return\n }\n\n // Extract LLM API key\n const llmApiKey = extractBearerToken(req)\n if (!llmApiKey) {\n sendJSON(res, 401, {\n error: { message: 'Authorization header with Bearer token is required', type: 'authentication_error' },\n })\n return\n }\n\n // ── Compress input ────────────────────────────────────────────\n let compressedInput = request.input\n let anyCompressed = false\n let totalTokensSaved = 0\n\n if (config.enabled && !pipeline.isCircuitOpen()) {\n try {\n const compressRoles = new Set(config.compressRoles)\n const compressible = inputToCompressibleMessages(request.input)\n\n if (compressible.length > 0) {\n const result = await compressMessages(\n compressible,\n pipeline.pipeline,\n pipeline.session,\n compressRoles,\n )\n\n compressedInput = applyCompressedToInput(request.input, result.messages)\n anyCompressed = result.anyCompressed\n totalTokensSaved = result.totalTokensSaved\n\n if (result.totalTokensSaved > 0) {\n logger.log(`[COMPRESS] Responses API: saved ${result.totalTokensSaved} tokens`)\n }\n }\n } catch (err) {\n if (err instanceof RSCCircuitOpenError) {\n logger.log('[DEGRADE] Circuit breaker open — passing through directly')\n } else {\n logger.log(`[ERROR] Compression failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n compressedInput = request.input\n }\n }\n\n // ── Build upstream request ────────────────────────────────────\n const upstreamUrl = `${config.upstreamBaseUrl}/v1/responses`\n const upstreamBody = { ...request, input: compressedInput }\n\n const upstreamHeaders: Record<string, string> = {\n 'Authorization': `Bearer ${llmApiKey}`,\n 'Content-Type': 'application/json',\n }\n\n if (request.stream) {\n upstreamHeaders['Accept'] = 'text/event-stream'\n }\n\n logger.log(`[RESPONSES] ${request.model} → ${upstreamUrl}`)\n\n try {\n const upstreamResponse = await fetch(upstreamUrl, {\n method: 'POST',\n headers: upstreamHeaders,\n body: JSON.stringify(upstreamBody),\n })\n\n // Handle upstream errors\n if (!upstreamResponse.ok) {\n const errorBody = await upstreamResponse.text()\n logger.log(`[RESPONSES] Upstream error ${upstreamResponse.status}: ${errorBody.slice(0, 500)}`)\n setCORSHeaders(res)\n res.writeHead(upstreamResponse.status, {\n 'Content-Type': upstreamResponse.headers.get('Content-Type') || 'application/json',\n })\n res.end(errorBody)\n return\n }\n\n // ── Streaming response ────────────────────────────────────\n if (request.stream && upstreamResponse.body) {\n const learningBuffer = anyCompressed\n ? createStreamLearningBuffer(pipeline.pipeline)\n : null\n\n await pipeResponsesSSE(\n upstreamResponse,\n res,\n (text) => learningBuffer?.append(text),\n () => learningBuffer?.flush(),\n totalTokensSaved,\n )\n return\n }\n\n // ── Non-streaming response ────────────────────────────────\n const responseBody = await upstreamResponse.text()\n\n // Adjust usage to reflect pre-compression token count\n let finalBody = responseBody\n if (totalTokensSaved > 0) {\n try {\n const parsed = JSON.parse(responseBody) as ResponsesResponse\n if (parsed?.usage?.input_tokens != null) {\n parsed.usage.input_tokens += totalTokensSaved\n if (parsed.usage.total_tokens != null) {\n parsed.usage.total_tokens += totalTokensSaved\n }\n finalBody = JSON.stringify(parsed)\n logger.log(`[TOKENS] Adjusted input_tokens by +${totalTokensSaved}`)\n }\n } catch {\n // Pass through unmodified on parse error\n }\n }\n\n setCORSHeaders(res)\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(finalBody)\n\n // Trigger learning from response (fire-and-forget)\n if (anyCompressed) {\n try {\n const parsed = JSON.parse(responseBody) as ResponsesResponse\n if (parsed?.output) {\n const text = extractOutputText(parsed.output)\n if (text.length > 0) {\n pipeline.pipeline.triggerLearning(text)\n }\n }\n } catch {\n // Ignore learning parse errors\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Upstream request failed: ${message}`)\n if (!res.headersSent) {\n sendJSON(res, 502, {\n error: { message: `Failed to reach upstream LLM: ${message}`, type: 'server_error' },\n })\n }\n }\n}\n","import * as http from 'node:http'\n\n/**\n * Pipe an OpenAI Responses API SSE stream from upstream to the client.\n *\n * Responses API SSE format differs from Chat Completions:\n * - Each chunk has both `event:` and `data:` lines\n * - Text deltas arrive as `response.output_text.delta` events\n * - Usage is reported in the `response.completed` event\n * - Stream ends with `data: [DONE]`\n *\n * When totalTokensSaved > 0, adjusts usage.input_tokens in the\n * `response.completed` event to reflect pre-compression token count.\n *\n * Writes each chunk immediately — zero buffering, zero added latency\n * (except for the single response.completed chunk which may get rewritten).\n */\nexport async function pipeResponsesSSE(\n upstreamResponse: Response,\n clientRes: http.ServerResponse,\n onContentDelta: (text: string) => void,\n onComplete: () => void,\n totalTokensSaved = 0,\n): Promise<void> {\n clientRes.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n })\n\n const reader = upstreamResponse.body!.getReader()\n const decoder = new TextDecoder()\n let lineBuf = ''\n let currentEvent = ''\n let usageAdjusted = false\n const needsAdjustment = totalTokensSaved > 0\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n\n // Fast path: no adjustment needed (or already done), write immediately\n if (!needsAdjustment || usageAdjusted) {\n clientRes.write(chunk)\n\n // Still parse for learning\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7).trim()\n } else if (line.startsWith('data: ') && currentEvent === 'response.output_text.delta') {\n try {\n const json = JSON.parse(line.slice(6))\n if (typeof json?.delta === 'string') {\n onContentDelta(json.delta)\n }\n } catch {\n // Malformed data — ignore for learning\n }\n }\n }\n continue\n }\n\n // Slow path: need to check for response.completed to adjust usage\n lineBuf += chunk\n const lines = lineBuf.split('\\n')\n lineBuf = lines.pop() || ''\n\n let adjusted = false\n const outputLines: string[] = []\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7).trim()\n outputLines.push(line)\n } else if (\n line.startsWith('data: ') &&\n currentEvent === 'response.completed' &&\n !usageAdjusted\n ) {\n // Adjust usage in the response.completed event\n try {\n const json = JSON.parse(line.slice(6))\n if (json?.response?.usage?.input_tokens != null) {\n json.response.usage.input_tokens += totalTokensSaved\n if (json.response.usage.total_tokens != null) {\n json.response.usage.total_tokens += totalTokensSaved\n }\n outputLines.push(`data: ${JSON.stringify(json)}`)\n usageAdjusted = true\n adjusted = true\n } else {\n outputLines.push(line)\n }\n } catch {\n outputLines.push(line)\n }\n } else {\n outputLines.push(line)\n\n // Learning: extract text deltas\n if (line.startsWith('data: ') && currentEvent === 'response.output_text.delta') {\n try {\n const json = JSON.parse(line.slice(6))\n if (typeof json?.delta === 'string') {\n onContentDelta(json.delta)\n }\n } catch {\n // Malformed data — ignore for learning\n }\n }\n }\n }\n\n if (adjusted) {\n const reconstructed = outputLines.join('\\n') + '\\n'\n clientRes.write(reconstructed)\n } else {\n clientRes.write(chunk)\n }\n }\n } finally {\n clientRes.end()\n onComplete()\n }\n}\n","import * as http from 'node:http'\nimport { handleChatCompletions } from './completions.js'\nimport { handleAnthropicMessages } from './messages.js'\nimport { handleResponses } from './responses.js'\nimport type { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport type { ResolvedConfig } from '../types.js'\n\nexport interface Logger {\n log(message: string): void\n}\n\nfunction setCORSHeaders(res: http.ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, anthropic-beta, anthropic-dangerous-direct-browser-access')\n res.setHeader('Access-Control-Max-Age', '86400')\n}\n\nfunction sendJSON(res: http.ServerResponse, status: number, body: unknown): void {\n setCORSHeaders(res)\n res.writeHead(status, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(body))\n}\n\nfunction readBody(req: http.IncomingMessage): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n req.on('data', (chunk: Buffer) => chunks.push(chunk))\n req.on('end', () => resolve(Buffer.concat(chunks)))\n req.on('error', reject)\n })\n}\n\n// ─── Upstream detection ──────────────────────────────────────────────\n// Determines whether the request is targeting Anthropic or OpenAI based\n// on headers and path. This lets the passthrough route unknown requests\n// to the correct upstream automatically.\n\ntype UpstreamTarget = 'anthropic' | 'openai'\n\nfunction detectUpstream(req: http.IncomingMessage, url: string): UpstreamTarget {\n // x-api-key header is Anthropic-specific\n if (req.headers['x-api-key']) return 'anthropic'\n // anthropic-version header is definitive\n if (req.headers['anthropic-version']) return 'anthropic'\n // Path-based hints\n if (url.startsWith('/v1/messages') || url.startsWith('/messages')) return 'anthropic'\n // Default to anthropic for ANTHROPIC_BASE_URL clients (Claude Code)\n // OpenAI clients set OPENAI_BASE_URL which includes /v1, so their\n // paths would be /chat/completions, /models, etc.\n return 'anthropic'\n}\n\nfunction getUpstreamBaseUrl(target: UpstreamTarget, config: ResolvedConfig): string {\n return target === 'anthropic'\n ? config.anthropicUpstreamUrl\n : config.upstreamBaseUrl\n}\n\n// ─── Header forwarding ──────────────────────────────────────────────\n// Copies all meaningful headers from the client request to the upstream.\n// This ensures new headers added by CC updates are forwarded automatically\n// instead of being silently dropped.\n\nconst HOP_BY_HOP = new Set([\n 'host', 'connection', 'keep-alive', 'transfer-encoding',\n 'te', 'trailer', 'upgrade', 'proxy-authorization', 'proxy-authenticate',\n])\n\nfunction buildUpstreamHeaders(req: http.IncomingMessage): Record<string, string> {\n const headers: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(req.headers)) {\n if (HOP_BY_HOP.has(key)) continue\n if (value === undefined) continue\n // node http parses multi-value headers as arrays; join them\n headers[key] = Array.isArray(value) ? value.join(', ') : value\n }\n\n return headers\n}\n\n// ─── Adaptive passthrough ────────────────────────────────────────────\n// Forwards ANY request to the detected upstream without modification.\n// This is the safety net: if CC starts calling a route Liminal doesn't\n// explicitly handle, it still works instead of returning 404.\n\nasync function passthroughToUpstream(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n fullUrl: string,\n config: ResolvedConfig,\n logger: Logger,\n): Promise<void> {\n const target = detectUpstream(req, fullUrl)\n const upstreamBase = getUpstreamBaseUrl(target, config)\n const upstreamUrl = `${upstreamBase}${fullUrl}`\n const method = req.method?.toUpperCase() ?? 'GET'\n\n logger.log(`[PASSTHROUGH] ${method} ${fullUrl} → ${target} (${upstreamUrl})`)\n\n const headers = buildUpstreamHeaders(req)\n\n try {\n const hasBody = method !== 'GET' && method !== 'HEAD'\n const body = hasBody ? await readBody(req) : undefined\n\n const upstreamRes = await fetch(upstreamUrl, {\n method,\n headers,\n body,\n })\n\n // Check if upstream is returning a streaming response\n const contentType = upstreamRes.headers.get('Content-Type') || 'application/json'\n const isStreaming = contentType.includes('text/event-stream')\n\n if (isStreaming && upstreamRes.body) {\n // Stream SSE responses chunk-by-chunk with zero buffering\n setCORSHeaders(res)\n res.writeHead(upstreamRes.status, {\n 'Content-Type': contentType,\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n })\n\n const reader = upstreamRes.body.getReader()\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n res.write(value)\n }\n } finally {\n res.end()\n }\n } else {\n // Buffer non-streaming responses normally\n const responseBody = await upstreamRes.arrayBuffer()\n setCORSHeaders(res)\n\n // Forward relevant response headers\n const responseHeaders: Record<string, string> = { 'Content-Type': contentType }\n const reqId = upstreamRes.headers.get('request-id')\n if (reqId) responseHeaders['request-id'] = reqId\n\n res.writeHead(upstreamRes.status, responseHeaders)\n res.end(Buffer.from(responseBody))\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Passthrough to ${target} failed: ${message}`)\n if (!res.headersSent) {\n setCORSHeaders(res)\n res.writeHead(502, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify({\n type: 'error',\n error: { type: 'api_error', message: `Liminal proxy: failed to reach ${target} upstream: ${message}` },\n }))\n }\n }\n}\n\nexport function createRequestHandler(\n pipeline: RSCPipelineWrapper,\n config: ResolvedConfig,\n logger: Logger,\n): (req: http.IncomingMessage, res: http.ServerResponse) => void {\n const startTime = Date.now()\n\n return async (req, res) => {\n try {\n const method = req.method?.toUpperCase() ?? ''\n const fullUrl = req.url ?? ''\n const url = fullUrl.split('?')[0] // Strip query string for route matching\n\n // Log every incoming request\n const authType = req.headers['x-api-key'] ? 'x-api-key' : req.headers['authorization'] ? 'bearer' : 'none'\n logger.log(`[REQUEST] ${method} ${fullUrl} (auth: ${authType})`)\n\n // CORS preflight\n if (method === 'OPTIONS') {\n setCORSHeaders(res)\n res.writeHead(204)\n res.end()\n return\n }\n\n // Health check (extended with session summary for `liminal status` / `liminal summary`)\n if (method === 'GET' && (url === '/health' || url === '/')) {\n const summary = pipeline.getSessionSummary()\n sendJSON(res, 200, {\n status: 'ok',\n version: config.rscApiKey ? 'connected' : 'no-api-key',\n rsc_connected: !pipeline.isCircuitOpen(),\n circuit_state: pipeline.getCircuitState(),\n session_id: summary.sessionId,\n uptime_ms: Date.now() - startTime,\n session: {\n tokens_processed: summary.tokensProcessed,\n tokens_saved: summary.tokensSaved,\n calls_total: summary.totalCalls,\n calls_compressed: summary.compressedCalls,\n calls_skipped: summary.skippedCalls,\n calls_failed: summary.failedCalls,\n patterns_learned: summary.patternsLearned,\n estimated_cost_saved_usd: summary.estimatedCostSaved,\n },\n })\n return\n }\n\n // ── Compression routes (Liminal value-add) ────────────────────\n\n // Main route: chat completions — compress before forwarding\n if (method === 'POST' && (url === '/v1/chat/completions' || url === '/chat/completions')) {\n const body = await readBody(req)\n let parsed: unknown\n try {\n parsed = JSON.parse(body.toString('utf-8'))\n } catch {\n sendJSON(res, 400, {\n error: { message: 'Invalid JSON body', type: 'invalid_request_error' },\n })\n return\n }\n\n await handleChatCompletions(req, res, parsed, pipeline, config, logger)\n return\n }\n\n // OpenAI Responses API — compress before forwarding (Codex, Cursor Agent)\n if (method === 'POST' && (url === '/v1/responses' || url === '/responses')) {\n const body = await readBody(req)\n let parsed: unknown\n try {\n parsed = JSON.parse(body.toString('utf-8'))\n } catch {\n sendJSON(res, 400, {\n error: { message: 'Invalid JSON body', type: 'invalid_request_error' },\n })\n return\n }\n\n await handleResponses(req, res, parsed, pipeline, config, logger)\n return\n }\n\n // Anthropic Messages route — compress before forwarding\n if (method === 'POST' && (url === '/v1/messages' || url === '/messages')) {\n const body = await readBody(req)\n let parsed: unknown\n try {\n parsed = JSON.parse(body.toString('utf-8'))\n } catch {\n sendJSON(res, 400, {\n type: 'error',\n error: { type: 'invalid_request_error', message: 'Invalid JSON body' },\n })\n return\n }\n\n await handleAnthropicMessages(req, res, parsed, pipeline, config, logger)\n return\n }\n\n // ── Adaptive passthrough (everything else) ────────────────────\n // Any route Liminal doesn't explicitly handle gets forwarded to\n // the detected upstream unchanged. This makes Liminal resilient\n // to Claude Code updates that add new API endpoints — they just\n // pass through transparently instead of hitting a 404.\n await passthroughToUpstream(req, res, fullUrl, config, logger)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n logger.log(`[ERROR] Proxy handler error: ${message}`)\n if (!res.headersSent) {\n sendJSON(res, 500, {\n error: { message: 'Internal proxy error', type: 'server_error' },\n })\n }\n }\n }\n}\n","import * as http from 'node:http'\n\nconst MAX_PORT_RETRIES = 5\n\nexport class ProxyServer {\n private server: http.Server | null = null\n private activePort: number | null = null\n private readonly requestedPort: number\n private readonly handler: (req: http.IncomingMessage, res: http.ServerResponse) => void\n\n constructor(\n port: number,\n handler: (req: http.IncomingMessage, res: http.ServerResponse) => void,\n ) {\n this.requestedPort = port\n this.handler = handler\n }\n\n async start(): Promise<number> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < MAX_PORT_RETRIES; attempt++) {\n const port = this.requestedPort + attempt\n try {\n await this.listen(port)\n this.activePort = port\n return port\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err))\n if ((err as NodeJS.ErrnoException).code !== 'EADDRINUSE') {\n throw lastError\n }\n }\n }\n\n throw lastError ?? new Error(`All ports ${this.requestedPort}-${this.requestedPort + MAX_PORT_RETRIES - 1} in use`)\n }\n\n private listen(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const server = http.createServer(this.handler)\n server.on('error', reject)\n server.listen(port, '127.0.0.1', () => {\n server.removeListener('error', reject)\n this.server = server\n resolve()\n })\n })\n }\n\n async stop(): Promise<void> {\n if (!this.server) return\n return new Promise((resolve) => {\n this.server!.close(() => {\n this.server = null\n this.activePort = null\n resolve()\n })\n })\n }\n\n isRunning(): boolean {\n return this.server !== null && this.server.listening\n }\n\n getPort(): number | null {\n return this.activePort\n }\n}\n","import { appendFileSync, statSync, renameSync, mkdirSync, existsSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { LOG_FILE, LOG_DIR } from '../config/paths.js'\nimport type { Logger } from '../proxy/handler.js'\n\nconst MAX_LOG_SIZE = 10 * 1024 * 1024 // 10 MB\nconst MAX_BACKUPS = 2\n\nexport class FileLogger implements Logger {\n private readonly logFile: string\n private readonly mirrorStdout: boolean\n\n constructor(options?: { logFile?: string; mirrorStdout?: boolean }) {\n this.logFile = options?.logFile ?? LOG_FILE\n this.mirrorStdout = options?.mirrorStdout ?? false\n\n // Ensure log directory exists\n const logDir = dirname(this.logFile)\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true })\n }\n }\n\n log(message: string): void {\n const timestamp = new Date().toISOString().slice(11, 23)\n const line = `[${timestamp}] ${message}\\n`\n\n try {\n appendFileSync(this.logFile, line)\n } catch {\n // If log write fails, try stdout as fallback\n process.stderr.write(`[LOG-WRITE-FAILED] ${line}`)\n }\n\n if (this.mirrorStdout) {\n process.stdout.write(line)\n }\n\n this.rotateIfNeeded()\n }\n\n private rotateIfNeeded(): void {\n try {\n const stats = statSync(this.logFile)\n if (stats.size <= MAX_LOG_SIZE) return\n\n // Rotate: liminal.log -> liminal.log.1 -> liminal.log.2 (drop oldest)\n for (let i = MAX_BACKUPS - 1; i >= 1; i--) {\n const from = `${this.logFile}.${i}`\n const to = `${this.logFile}.${i + 1}`\n if (existsSync(from)) renameSync(from, to)\n }\n renameSync(this.logFile, `${this.logFile}.1`)\n } catch {\n // Rotation failure is non-fatal\n }\n }\n\n getLogFile(): string {\n return this.logFile\n }\n}\n\n/**\n * A simple logger that only writes to stdout (for use during init or when log file isn't available).\n */\nexport class ConsoleLogger implements Logger {\n log(message: string): void {\n const timestamp = new Date().toISOString().slice(11, 23)\n process.stdout.write(`[${timestamp}] ${message}\\n`)\n }\n}\n","import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs'\nimport { fork } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { PID_FILE } from '../config/paths.js'\nimport type { ProxyServer } from '../proxy/server.js'\nimport type { Logger } from '../proxy/handler.js'\n\n/**\n * Write the current process PID to ~/.liminal/liminal.pid.\n */\nexport function writePidFile(pid: number): void {\n writeFileSync(PID_FILE, String(pid), 'utf-8')\n}\n\n/**\n * Read PID from ~/.liminal/liminal.pid. Returns null if file doesn't exist.\n */\nexport function readPidFile(): number | null {\n if (!existsSync(PID_FILE)) return null\n try {\n const content = readFileSync(PID_FILE, 'utf-8').trim()\n const pid = parseInt(content, 10)\n return isNaN(pid) ? null : pid\n } catch {\n return null\n }\n}\n\n/**\n * Remove the PID file.\n */\nexport function removePidFile(): void {\n try {\n if (existsSync(PID_FILE)) unlinkSync(PID_FILE)\n } catch {\n // Ignore — file may already be gone\n }\n}\n\n/**\n * Check if a process with the given PID is alive.\n */\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Check if the Liminal daemon is currently running.\n * Cleans up stale PID files automatically.\n */\nexport function isDaemonRunning(): { running: boolean; pid?: number } {\n const pid = readPidFile()\n if (pid === null) return { running: false }\n\n if (isProcessAlive(pid)) {\n return { running: true, pid }\n }\n\n // Stale PID file — process is dead\n removePidFile()\n return { running: false }\n}\n\n/**\n * Set up signal handlers for graceful shutdown.\n */\nexport function setupSignalHandlers(server: ProxyServer, logger: Logger): void {\n const shutdown = async (signal: string) => {\n logger.log(`[DAEMON] Received ${signal}, shutting down...`)\n try {\n await server.stop()\n } catch {\n // Best-effort server stop\n }\n removePidFile()\n logger.log('[DAEMON] Stopped.')\n process.exit(0)\n }\n\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n process.on('SIGINT', () => shutdown('SIGINT'))\n\n process.on('uncaughtException', (err) => {\n logger.log(`[FATAL] Uncaught exception: ${err.message}`)\n removePidFile()\n process.exit(1)\n })\n\n process.on('unhandledRejection', (reason) => {\n const message = reason instanceof Error ? reason.message : String(reason)\n logger.log(`[FATAL] Unhandled rejection: ${message}`)\n removePidFile()\n process.exit(1)\n })\n}\n\n/**\n * Fork a detached child process to run the daemon in the background.\n * Returns the child PID.\n */\nexport function forkDaemon(binPath: string, extraArgs: string[] = []): number {\n const child = fork(binPath, ['start', '--_forked', ...extraArgs], {\n detached: true,\n stdio: 'ignore',\n })\n\n child.unref()\n return child.pid!\n}\n\n/**\n * Resolve the bin.ts/bin.js entry point path from import.meta.url.\n */\nexport function resolveBinPath(importMetaUrl: string): string {\n return fileURLToPath(importMetaUrl)\n}\n\n/**\n * Sleep for a given number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { loadConfig, applyOverrides, isConfigured } from '../config/loader.js'\nimport { RSCPipelineWrapper } from '../rsc/pipeline.js'\nimport { createRequestHandler } from '../proxy/handler.js'\nimport { ProxyServer } from '../proxy/server.js'\nimport { FileLogger } from '../daemon/logger.js'\nimport {\n isDaemonRunning,\n writePidFile,\n setupSignalHandlers,\n forkDaemon,\n resolveBinPath,\n} from '../daemon/lifecycle.js'\nimport type { ResolvedConfig, Tool } from '../types.js'\nimport { printBanner } from '../version.js'\n\nexport async function startCommand(flags: Map<string, string | true>): Promise<void> {\n const isDaemon = flags.has('d') || flags.has('daemon')\n const isForked = flags.has('_forked')\n\n // Check if already running (skip for forked processes — parent already checked)\n if (!isForked) {\n const state = isDaemonRunning()\n if (state.running) {\n console.error(`Liminal daemon is already running (PID ${state.pid}).`)\n console.error('Use \"liminal stop\" first, or \"liminal status\" to check.')\n process.exit(1)\n }\n }\n\n // Check config\n if (!isConfigured()) {\n console.error('Liminal is not configured. Run \"liminal init\" first.')\n process.exit(1)\n }\n\n // Load and apply config\n let config = loadConfig()\n const portOverride = flags.get('port')\n const upstreamOverride = flags.get('upstream')\n config = applyOverrides(config, {\n ...(typeof portOverride === 'string' ? { port: parseInt(portOverride, 10) } : {}),\n ...(typeof upstreamOverride === 'string' ? { upstreamBaseUrl: upstreamOverride } : {}),\n })\n\n // Background mode: fork and exit parent\n if (isDaemon && !isForked) {\n const extraArgs: string[] = []\n if (portOverride) extraArgs.push('--port', String(portOverride))\n if (upstreamOverride) extraArgs.push('--upstream', String(upstreamOverride))\n\n const binPath = resolveBinPath(import.meta.url)\n const childPid = forkDaemon(binPath, extraArgs)\n\n console.log(`Liminal daemon started in background (PID ${childPid})`)\n console.log(`Proxy: http://127.0.0.1:${config.port}/v1`)\n console.log('Logs: ~/.liminal/logs/liminal.log')\n process.exit(0)\n }\n\n // Foreground mode: run the server in this process\n const isForeground = !isDaemon || isForked\n const logger = new FileLogger({ mirrorStdout: isForeground && !isForked })\n\n // Build the resolved config for the proxy\n const resolvedConfig: ResolvedConfig = {\n rscApiKey: config.apiKey,\n rscBaseUrl: config.apiBaseUrl,\n proxyPort: config.port,\n compressionThreshold: config.compressionThreshold,\n compressRoles: config.compressRoles,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs || undefined,\n upstreamBaseUrl: config.upstreamBaseUrl,\n anthropicUpstreamUrl: config.anthropicUpstreamUrl,\n enabled: config.enabled,\n tools: config.tools as Tool[],\n }\n\n // Create RSC pipeline\n const pipeline = new RSCPipelineWrapper({\n rscApiKey: config.apiKey,\n rscBaseUrl: config.apiBaseUrl,\n compressionThreshold: config.compressionThreshold,\n learnFromResponses: config.learnFromResponses,\n latencyBudgetMs: config.latencyBudgetMs || undefined,\n })\n\n // Wire up pipeline events for logging\n pipeline.events.on('compression', (event) => {\n if (event.tokensSaved > 0) {\n logger.log(`[LIMINAL] Compressed: ${event.tokensSaved} tokens saved (${event.ratio.toFixed(3)} ratio)`)\n }\n })\n pipeline.events.on('compression_skipped', (event) => {\n logger.log(`[LIMINAL] Skipped: ${event.reason}`)\n })\n pipeline.events.on('error', (event) => {\n logger.log(`[LIMINAL] Error: ${event.error.message}`)\n })\n pipeline.events.on('degradation', (event) => {\n logger.log(`[LIMINAL] Circuit ${event.circuitState}: ${event.reason}`)\n })\n\n // Create server\n const handler = createRequestHandler(pipeline, resolvedConfig, logger)\n const server = new ProxyServer(config.port, handler)\n\n // Setup graceful shutdown\n setupSignalHandlers(server, logger)\n\n // Start listening\n try {\n const actualPort = await server.start()\n writePidFile(process.pid)\n\n logger.log(`[DAEMON] Liminal proxy started on http://127.0.0.1:${actualPort}`)\n logger.log(`[DAEMON] Upstream (OpenAI): ${config.upstreamBaseUrl}`)\n logger.log(`[DAEMON] Upstream (Anthropic): ${config.anthropicUpstreamUrl}`)\n logger.log(`[DAEMON] Liminal API: ${config.apiBaseUrl}`)\n logger.log(`[DAEMON] PID: ${process.pid}`)\n\n if (isForeground && !isForked) {\n printBanner()\n console.log(` Liminal proxy running on http://127.0.0.1:${actualPort}/v1`)\n console.log(` Upstream: ${config.upstreamBaseUrl}`)\n console.log()\n console.log(' Point your AI tool\\'s base URL here. Press Ctrl+C to stop.')\n console.log()\n }\n\n // Check RSC API health on startup\n const healthy = await pipeline.healthCheck()\n if (healthy) {\n logger.log('[DAEMON] Liminal API health check: OK')\n } else {\n logger.log('[DAEMON] Liminal API health check: FAILED (will retry on first request)')\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.error(`Failed to start proxy: ${message}`)\n process.exit(1)\n }\n}\n","import {\n isDaemonRunning,\n readPidFile,\n removePidFile,\n isProcessAlive,\n sleep,\n} from '../daemon/lifecycle.js'\n\nexport async function stopCommand(): Promise<void> {\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal daemon is not running.')\n return\n }\n\n const pid = state.pid\n console.log(`Stopping Liminal daemon (PID ${pid})...`)\n\n // Send SIGTERM for graceful shutdown\n try {\n process.kill(pid, 'SIGTERM')\n } catch {\n // Process may have already exited\n removePidFile()\n console.log('Liminal daemon stopped.')\n return\n }\n\n // Poll for up to 5 seconds\n for (let i = 0; i < 25; i++) {\n await sleep(200)\n if (!isProcessAlive(pid)) {\n removePidFile()\n console.log(`Liminal daemon stopped (PID ${pid}).`)\n return\n }\n }\n\n // Force kill after timeout\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n // Already dead\n }\n\n removePidFile()\n console.log(`Liminal daemon force-killed (PID ${pid}).`)\n}\n","import { isDaemonRunning } from '../daemon/lifecycle.js'\nimport { loadConfig, isConfigured } from '../config/loader.js'\n\nexport async function statusCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log('Liminal: not configured')\n console.log('Run \"liminal init\" to set up.')\n return\n }\n\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal Daemon: stopped')\n console.log('Run \"liminal start\" to start the proxy.')\n return\n }\n\n const config = loadConfig()\n const port = config.port\n\n // Try to reach the daemon's /health endpoint\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(3000),\n })\n const data = await res.json() as {\n status: string\n circuit_state: string\n session_id: string\n uptime_ms: number\n session?: {\n tokens_processed: number\n tokens_saved: number\n calls_total: number\n calls_compressed: number\n calls_skipped: number\n calls_failed: number\n }\n }\n\n const uptime = formatUptime(data.uptime_ms)\n\n console.log(`Liminal Daemon: running (PID ${state.pid}, port ${port})`)\n console.log(`Circuit: ${data.circuit_state}`)\n console.log(`Session: ${data.session_id}`)\n console.log(`Uptime: ${uptime}`)\n\n if (data.session) {\n const s = data.session\n const savingsPercent = s.tokens_processed > 0\n ? ((s.tokens_saved / s.tokens_processed) * 100).toFixed(1)\n : '0.0'\n console.log()\n console.log(`Tokens: ${s.tokens_processed.toLocaleString()} processed, ${s.tokens_saved.toLocaleString()} saved (${savingsPercent}%)`)\n console.log(`Calls: ${s.calls_total} total (${s.calls_compressed} compressed, ${s.calls_skipped} skipped, ${s.calls_failed} failed)`)\n }\n } catch {\n // Can't reach the daemon, but PID is alive — might still be starting\n console.log(`Liminal Daemon: running (PID ${state.pid}, port ${port})`)\n console.log('Circuit: unknown (could not reach /health)')\n }\n}\n\nfunction formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`\n if (hours > 0) return `${hours}h ${minutes % 60}m`\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`\n return `${seconds}s`\n}\n","import { isDaemonRunning } from '../daemon/lifecycle.js'\nimport { loadConfig, isConfigured } from '../config/loader.js'\n\nexport async function summaryCommand(): Promise<void> {\n if (!isConfigured()) {\n console.log('Liminal is not configured. Run \"liminal init\" first.')\n return\n }\n\n const state = isDaemonRunning()\n\n if (!state.running || !state.pid) {\n console.log('Liminal daemon is not running. Start it with \"liminal start\".')\n return\n }\n\n const config = loadConfig()\n const port = config.port\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(3000),\n })\n const data = await res.json() as {\n circuit_state: string\n session_id: string\n uptime_ms: number\n session?: {\n tokens_processed: number\n tokens_saved: number\n calls_total: number\n calls_compressed: number\n calls_skipped: number\n calls_failed: number\n patterns_learned: number\n estimated_cost_saved_usd: number\n }\n }\n\n const uptime = formatUptime(data.uptime_ms)\n\n console.log()\n console.log(` Session: ${data.session_id}`)\n console.log(` Uptime: ${uptime}`)\n console.log()\n\n if (data.session) {\n const s = data.session\n const savingsPercent = s.tokens_processed > 0\n ? ((s.tokens_saved / s.tokens_processed) * 100).toFixed(1)\n : '0.0'\n const compressionRate = s.calls_total > 0\n ? ((s.calls_compressed / s.calls_total) * 100).toFixed(0)\n : '0'\n\n console.log(' Compression:')\n console.log(` Tokens processed: ${s.tokens_processed.toLocaleString()}`)\n console.log(` Tokens saved: ${s.tokens_saved.toLocaleString()} (${savingsPercent}%)`)\n console.log(` Compression rate: ${compressionRate}% of calls compressed`)\n console.log(` Patterns learned: ${s.patterns_learned.toLocaleString()}`)\n console.log()\n console.log(' Calls:')\n console.log(` Total: ${s.calls_total}`)\n console.log(` Compressed: ${s.calls_compressed}`)\n console.log(` Skipped: ${s.calls_skipped}`)\n console.log(` Failed: ${s.calls_failed}`)\n console.log()\n console.log(' Cost Savings:')\n console.log(` Estimated: $${s.estimated_cost_saved_usd.toFixed(4)} USD`)\n console.log()\n } else {\n console.log(' No session data available yet.')\n console.log()\n }\n\n console.log(` Circuit: ${data.circuit_state}`)\n console.log(` API: ${config.apiBaseUrl}`)\n console.log(` Upstream: ${config.upstreamBaseUrl}`)\n console.log()\n } catch {\n console.error('Could not reach the Liminal daemon. Is it running?')\n console.error(`Tried http://127.0.0.1:${port}/health`)\n process.exit(1)\n }\n}\n\nfunction formatUptime(ms: number): string {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n\n if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`\n if (hours > 0) return `${hours}h ${minutes % 60}m`\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`\n return `${seconds}s`\n}\n","import { loadConfig, saveConfig, isConfigured, maskApiKey } from '../config/loader.js'\nimport { CONFIGURABLE_KEYS } from '../config/schema.js'\nimport { CONFIG_FILE } from '../config/paths.js'\n\nexport async function configCommand(flags: Map<string, string | true>): Promise<void> {\n const getKey = flags.get('get')\n const setKv = flags.get('set')\n\n // rsc config --get <key>\n if (typeof getKey === 'string') {\n if (!isConfigured()) {\n console.error('Liminal is not configured. Run \"liminal init\" first.')\n process.exit(1)\n }\n const config = loadConfig()\n const value = (config as unknown as Record<string, unknown>)[getKey]\n if (value === undefined) {\n console.error(`Unknown config key: ${getKey}`)\n process.exit(1)\n }\n console.log(getKey === 'apiKey' ? maskApiKey(String(value)) : String(value))\n return\n }\n\n // rsc config --set <key>=<value>\n if (typeof setKv === 'string') {\n const eqIdx = setKv.indexOf('=')\n if (eqIdx === -1) {\n console.error('Usage: liminal config --set key=value')\n process.exit(1)\n }\n const key = setKv.slice(0, eqIdx)\n const rawValue = setKv.slice(eqIdx + 1)\n\n if (!CONFIGURABLE_KEYS.has(key) && key !== 'apiKey') {\n console.error(`Unknown or non-configurable key: ${key}`)\n console.error(`Configurable keys: ${[...CONFIGURABLE_KEYS].join(', ')}`)\n process.exit(1)\n }\n\n // Parse value based on key type\n let parsedValue: unknown = rawValue\n if (key === 'port' || key === 'compressionThreshold' || key === 'latencyBudgetMs') {\n parsedValue = parseInt(rawValue, 10)\n if (isNaN(parsedValue as number)) {\n console.error(`Invalid number for ${key}: ${rawValue}`)\n process.exit(1)\n }\n } else if (key === 'learnFromResponses' || key === 'enabled') {\n parsedValue = rawValue === 'true' || rawValue === '1'\n } else if (key === 'compressRoles') {\n parsedValue = rawValue.split(',').map((s) => s.trim())\n }\n\n saveConfig({ [key]: parsedValue })\n console.log(`Set ${key} = ${key === 'apiKey' ? maskApiKey(rawValue) : rawValue}`)\n return\n }\n\n // rsc config (no flags) — show all\n if (!isConfigured()) {\n console.log(`Liminal is not configured. Run \"liminal init\" first.`)\n console.log(`Config file: ${CONFIG_FILE}`)\n return\n }\n\n const config = loadConfig()\n console.log()\n console.log(` Config: ${CONFIG_FILE}`)\n console.log()\n console.log(` apiKey: ${maskApiKey(config.apiKey)}`)\n console.log(` apiBaseUrl: ${config.apiBaseUrl}`)\n console.log(` upstreamBaseUrl: ${config.upstreamBaseUrl}`)\n console.log(` anthropicUpstreamUrl: ${config.anthropicUpstreamUrl}`)\n console.log(` tools: ${config.tools.length > 0 ? config.tools.join(', ') : '(none)'}`)\n console.log(` port: ${config.port}`)\n console.log(` compressionThreshold: ${config.compressionThreshold}`)\n console.log(` compressRoles: ${config.compressRoles.join(', ')}`)\n console.log(` learnFromResponses: ${config.learnFromResponses}`)\n console.log(` latencyBudgetMs: ${config.latencyBudgetMs || 'auto'}`)\n console.log(` enabled: ${config.enabled}`)\n console.log()\n}\n","import { readFileSync, existsSync, statSync, createReadStream } from 'node:fs'\nimport { watchFile, unwatchFile } from 'node:fs'\nimport { LOG_FILE } from '../config/paths.js'\n\nexport async function logsCommand(flags: Map<string, string | true>): Promise<void> {\n const follow = flags.has('follow') || flags.has('f')\n const linesFlag = flags.get('lines') ?? flags.get('n')\n const lines = typeof linesFlag === 'string' ? parseInt(linesFlag, 10) : 50\n\n if (!existsSync(LOG_FILE)) {\n console.log('No log file found. Start the daemon with \"liminal start\" to generate logs.')\n return\n }\n\n // Read and display last N lines\n const content = readFileSync(LOG_FILE, 'utf-8')\n const allLines = content.split('\\n')\n const tail = allLines.slice(-lines - 1) // -1 to account for trailing newline\n process.stdout.write(tail.join('\\n'))\n\n if (!follow) return\n\n // Follow mode: watch for changes and stream new content\n let lastSize = statSync(LOG_FILE).size\n\n watchFile(LOG_FILE, { interval: 500 }, (curr) => {\n if (curr.size > lastSize) {\n const stream = createReadStream(LOG_FILE, { start: lastSize, encoding: 'utf-8' })\n stream.on('data', (chunk) => process.stdout.write(chunk as string))\n stream.on('end', () => { lastSize = curr.size })\n } else if (curr.size < lastSize) {\n // File was rotated — read from beginning\n lastSize = 0\n }\n })\n\n // Keep the process alive and handle Ctrl+C\n process.on('SIGINT', () => {\n unwatchFile(LOG_FILE)\n process.exit(0)\n })\n\n // Block forever\n await new Promise(() => {})\n}\n","import { existsSync, rmSync, readFileSync } from 'node:fs'\nimport {\n detectShellProfile,\n removeLiminalFromShellProfile,\n findLiminalExportsInProfile,\n} from '../config/shell.js'\nimport { LIMINAL_DIR, CONFIG_FILE } from '../config/paths.js'\nimport { isDaemonRunning, removePidFile, isProcessAlive, sleep } from '../daemon/lifecycle.js'\nimport { CONNECTORS, getConnectors } from '../connectors/index.js'\nimport { selectPrompt } from '../ui/prompts.js'\nimport type { ConnectorId } from '../connectors/types.js'\n\n// ─── ANSI helpers ────────────────────────────────────────────────────\nconst BOLD = '\\x1b[1m'\nconst DIM = '\\x1b[2m'\nconst CYAN = '\\x1b[36m'\nconst GREEN = '\\x1b[32m'\nconst YELLOW = '\\x1b[33m'\nconst RED = '\\x1b[31m'\nconst RESET = '\\x1b[0m'\n\n/**\n * Load the list of configured tools from ~/.liminal/config.json.\n */\nfunction loadConfiguredTools(): ConnectorId[] {\n if (!existsSync(CONFIG_FILE)) return []\n try {\n const raw = readFileSync(CONFIG_FILE, 'utf-8')\n const config = JSON.parse(raw)\n if (Array.isArray(config.tools)) return config.tools as ConnectorId[]\n } catch {\n // Corrupted config — treat as empty\n }\n return []\n}\n\nexport async function uninstallCommand(): Promise<void> {\n console.log()\n console.log(` ${BOLD}Liminal Uninstall${RESET}`)\n console.log()\n\n // ── 1. Confirm ────────────────────────────────────────────────\n const confirm = await selectPrompt<boolean>({\n message: 'Remove Liminal configuration and restore tool settings?',\n options: [\n { label: 'Yes', value: true, description: 'Undo all Liminal setup' },\n { label: 'No', value: false, description: 'Cancel' },\n ],\n defaultIndex: 1, // Default to No for safety\n })\n\n if (confirm !== true) {\n console.log()\n console.log(' Cancelled.')\n console.log()\n return\n }\n\n console.log()\n\n // ── 2. Stop daemon if running ─────────────────────────────────\n const state = isDaemonRunning()\n if (state.running && state.pid) {\n console.log(` Stopping Liminal daemon (PID ${state.pid})...`)\n try {\n process.kill(state.pid, 'SIGTERM')\n // Wait up to 3 seconds for graceful shutdown\n for (let i = 0; i < 15; i++) {\n await sleep(200)\n if (!isProcessAlive(state.pid)) break\n }\n if (isProcessAlive(state.pid)) {\n process.kill(state.pid, 'SIGKILL')\n }\n } catch {\n // Already dead\n }\n removePidFile()\n console.log(` ${GREEN}✓${RESET} Daemon stopped`)\n } else {\n console.log(` ${DIM}·${RESET} Daemon not running`)\n }\n\n // ── 3. Remove shell profile exports ───────────────────────────\n const profile = detectShellProfile()\n if (profile) {\n const existing = findLiminalExportsInProfile(profile)\n if (existing.length > 0) {\n const removed = removeLiminalFromShellProfile(profile)\n if (removed.length > 0) {\n console.log(` ${GREEN}✓${RESET} Removed ${removed.length} line${removed.length > 1 ? 's' : ''} from ${profile.name}:`)\n for (const line of removed) {\n const trimmed = line.trim()\n if (trimmed && trimmed !== '# Liminal — route AI tools through compression proxy') {\n console.log(` ${DIM}${trimmed}${RESET}`)\n }\n }\n }\n } else {\n console.log(` ${DIM}·${RESET} No Liminal exports found in ${profile.name}`)\n }\n }\n\n // ── 4. Run connector-specific teardown ────────────────────────\n const configuredTools = loadConfiguredTools()\n const allTools = configuredTools.length > 0 ? configuredTools : CONNECTORS.map((c) => c.info.id)\n const connectors = getConnectors(allTools)\n\n const manualSteps: Array<{ label: string; steps: string[] }> = []\n\n for (const connector of connectors) {\n const result = await connector.teardown()\n if (result.manualSteps.length > 0 && !connector.info.automatable) {\n manualSteps.push({\n label: connector.info.label,\n steps: result.manualSteps,\n })\n }\n }\n\n if (manualSteps.length > 0) {\n console.log()\n console.log(` ${YELLOW}Manual steps needed:${RESET}`)\n for (const { label, steps } of manualSteps) {\n console.log()\n console.log(` ${BOLD}${label}:${RESET}`)\n for (const step of steps) {\n console.log(` ${step}`)\n }\n }\n }\n\n // ── 5. Optionally remove ~/.liminal/ ──────────────────────────\n if (existsSync(LIMINAL_DIR)) {\n console.log()\n const removeData = await selectPrompt<boolean>({\n message: 'Remove ~/.liminal/ directory? (config, logs, PID file)',\n options: [\n { label: 'Yes', value: true, description: 'Delete all Liminal data' },\n { label: 'No', value: false, description: 'Keep config and logs' },\n ],\n defaultIndex: 1, // Default to keep\n })\n\n if (removeData === true) {\n rmSync(LIMINAL_DIR, { recursive: true, force: true })\n console.log(` ${GREEN}✓${RESET} Removed ~/.liminal/`)\n } else {\n console.log(` ${DIM}·${RESET} Kept ~/.liminal/`)\n }\n }\n\n // ── 6. Summary ────────────────────────────────────────────────\n console.log()\n console.log(` ${GREEN}Liminal has been uninstalled.${RESET}`)\n console.log()\n console.log(` ${DIM}Your AI tools will connect directly to their APIs.${RESET}`)\n console.log(` ${DIM}Restart your terminal for shell changes to take effect.${RESET}`)\n\n if (manualSteps.length > 0) {\n console.log(` ${YELLOW}Don't forget the manual steps above for ${manualSteps.map((s) => s.label).join(', ')}.${RESET}`)\n }\n\n console.log()\n console.log(` ${DIM}To reinstall: npx @cognisos/liminal init${RESET}`)\n console.log()\n}\n","import { VERSION } from './version.js'\nimport { initCommand } from './commands/init.js'\nimport { loginCommand } from './commands/login.js'\nimport { logoutCommand } from './commands/logout.js'\nimport { startCommand } from './commands/start.js'\nimport { stopCommand } from './commands/stop.js'\nimport { statusCommand } from './commands/status.js'\nimport { summaryCommand } from './commands/summary.js'\nimport { configCommand } from './commands/config.js'\nimport { logsCommand } from './commands/logs.js'\nimport { uninstallCommand } from './commands/uninstall.js'\n\nconst USAGE = `\n liminal v${VERSION} — Transparent LLM context compression proxy\n\n Usage:\n liminal init Set up Liminal (login, config)\n liminal login Log in or create an account\n liminal logout Log out of your account\n liminal start [-d] [--port PORT] Start the compression proxy\n liminal stop Stop the running proxy\n liminal status Show proxy health and stats\n liminal summary Detailed session metrics\n liminal config [--set k=v] [--get k] View or edit configuration\n liminal logs [--follow] [--lines N] View proxy logs\n liminal uninstall Remove Liminal configuration\n\n Options:\n -h, --help Show this help message\n -v, --version Show version number\n\n Getting started:\n 1. liminal init # Log in + select tools\n 2. liminal start # Start the proxy\n 3. Connect your AI tools:\n Claude Code: export ANTHROPIC_BASE_URL=http://localhost:3141\n Codex: export OPENAI_BASE_URL=http://localhost:3141/v1\n Cursor: Settings > Models > Base URL > http://localhost:3141/v1\n`\n\nfunction parseArgs(argv: string[]): { command: string; flags: Map<string, string | true> } {\n const command = argv[2] ?? ''\n const flags = new Map<string, string | true>()\n\n for (let i = 3; i < argv.length; i++) {\n const arg = argv[i]\n if (arg.startsWith('--')) {\n const key = arg.slice(2)\n // Check if next arg is a value (not another flag)\n if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {\n flags.set(key, argv[i + 1])\n i++\n } else {\n flags.set(key, true)\n }\n } else if (arg.startsWith('-') && arg.length === 2) {\n const key = arg.slice(1)\n if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {\n flags.set(key, argv[i + 1])\n i++\n } else {\n flags.set(key, true)\n }\n }\n }\n\n return { command, flags }\n}\n\nasync function main(): Promise<void> {\n const { command, flags } = parseArgs(process.argv)\n\n // Global flags — handle --help and --version as both commands and flags\n if (flags.has('h') || flags.has('help') || command === 'help' || command === '--help' || command === '-h') {\n console.log(USAGE)\n process.exit(0)\n }\n\n if (flags.has('v') || flags.has('version') || command === 'version' || command === '--version' || command === '-v') {\n console.log(VERSION)\n process.exit(0)\n }\n\n try {\n switch (command) {\n case 'init':\n await initCommand()\n break\n\n case 'login':\n await loginCommand()\n break\n\n case 'logout':\n await logoutCommand()\n break\n\n case 'start':\n await startCommand(flags)\n break\n\n case 'stop':\n await stopCommand()\n break\n\n case 'status':\n await statusCommand()\n break\n\n case 'summary':\n await summaryCommand()\n break\n\n case 'config':\n await configCommand(flags)\n break\n\n case 'logs':\n await logsCommand(flags)\n break\n\n case 'uninstall':\n await uninstallCommand()\n break\n\n case '':\n console.log(USAGE)\n process.exit(0)\n break\n\n default:\n console.error(`Unknown command: ${command}`)\n console.log(USAGE)\n process.exit(1)\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.error(`Error: ${message}`)\n process.exit(1)\n }\n}\n\nmain()\n"],"mappings":"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","names":["existsSync","readFileSync","writeFileSync","join","homedir","stdin","stdout","execSync","existsSync","readFileSync","join","homedir","ENV_VAR","INFO","getCurrentBaseUrl","existsSync","join","homedir","INFO","ENV_VAR","INFO","getCurrentBaseUrl","RSCCircuitOpenError","lines","RSCCircuitOpenError","RSCCircuitOpenError","lines","setCORSHeaders","RSCCircuitOpenError","RSCCircuitOpenError","lines","setCORSHeaders","sendJSON","extractBearerToken","RSCCircuitOpenError","setCORSHeaders","sendJSON","appendFileSync","mkdirSync","existsSync","dirname","dirname","existsSync","mkdirSync","appendFileSync","readFileSync","writeFileSync","existsSync","writeFileSync","existsSync","readFileSync","formatUptime","config","readFileSync","existsSync","statSync","existsSync","readFileSync","statSync","existsSync","readFileSync","BOLD","DIM","GREEN","YELLOW","RESET","existsSync","readFileSync","BOLD","GREEN","DIM","YELLOW"]}
|