@cognisos/liminal 0.2.0 → 0.2.1
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 +122 -46
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/version.ts
|
|
4
|
-
var VERSION = true ? "0.2.
|
|
4
|
+
var VERSION = true ? "0.2.1" : "0.2.1";
|
|
5
5
|
var BANNER_LINES = [
|
|
6
6
|
" ___ ___ _____ ______ ___ ________ ________ ___",
|
|
7
7
|
"|\\ \\ |\\ \\|\\ _ \\ _ \\|\\ \\|\\ ___ \\|\\ __ \\|\\ \\",
|
|
@@ -24,6 +24,9 @@ function printBanner() {
|
|
|
24
24
|
// src/commands/init.ts
|
|
25
25
|
import { createInterface } from "readline/promises";
|
|
26
26
|
import { stdin, stdout } from "process";
|
|
27
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, appendFileSync } from "fs";
|
|
28
|
+
import { join as join2 } from "path";
|
|
29
|
+
import { homedir as homedir2 } from "os";
|
|
27
30
|
import { RSCTransport, CircuitBreaker } from "@cognisos/rsc-sdk";
|
|
28
31
|
|
|
29
32
|
// src/config/loader.ts
|
|
@@ -350,33 +353,58 @@ async function multiSelectPrompt(config) {
|
|
|
350
353
|
}
|
|
351
354
|
|
|
352
355
|
// src/commands/init.ts
|
|
353
|
-
function
|
|
356
|
+
function detectShellProfile() {
|
|
357
|
+
const shell = process.env.SHELL || "";
|
|
358
|
+
const home = homedir2();
|
|
359
|
+
if (shell.endsWith("/zsh")) {
|
|
360
|
+
const zshrc = join2(home, ".zshrc");
|
|
361
|
+
return { name: "~/.zshrc", path: zshrc };
|
|
362
|
+
}
|
|
363
|
+
if (shell.endsWith("/bash")) {
|
|
364
|
+
const bashProfile = join2(home, ".bash_profile");
|
|
365
|
+
if (existsSync2(bashProfile)) {
|
|
366
|
+
return { name: "~/.bash_profile", path: bashProfile };
|
|
367
|
+
}
|
|
368
|
+
return { name: "~/.bashrc", path: join2(home, ".bashrc") };
|
|
369
|
+
}
|
|
370
|
+
const candidates = [
|
|
371
|
+
{ name: "~/.zshrc", path: join2(home, ".zshrc") },
|
|
372
|
+
{ name: "~/.bashrc", path: join2(home, ".bashrc") },
|
|
373
|
+
{ name: "~/.profile", path: join2(home, ".profile") }
|
|
374
|
+
];
|
|
375
|
+
for (const c of candidates) {
|
|
376
|
+
if (existsSync2(c.path)) return c;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
function getExportLines(tools, port) {
|
|
354
381
|
const base = `http://127.0.0.1:${port}`;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
console.log();
|
|
372
|
-
break;
|
|
373
|
-
case "openai-compatible":
|
|
374
|
-
console.log(" OpenAI-compatible tools:");
|
|
375
|
-
console.log(` Set your base URL to: ${base}/v1`);
|
|
376
|
-
console.log();
|
|
377
|
-
break;
|
|
382
|
+
const lines = [];
|
|
383
|
+
if (tools.includes("claude-code")) {
|
|
384
|
+
lines.push(`export ANTHROPIC_BASE_URL=${base}`);
|
|
385
|
+
}
|
|
386
|
+
if (tools.includes("codex") || tools.includes("openai-compatible")) {
|
|
387
|
+
lines.push(`export OPENAI_BASE_URL=${base}/v1`);
|
|
388
|
+
}
|
|
389
|
+
return lines;
|
|
390
|
+
}
|
|
391
|
+
function lineExistsInFile(filePath, line) {
|
|
392
|
+
if (!existsSync2(filePath)) return false;
|
|
393
|
+
try {
|
|
394
|
+
const content = readFileSync2(filePath, "utf-8");
|
|
395
|
+
return content.includes(line);
|
|
396
|
+
} catch {
|
|
397
|
+
return false;
|
|
378
398
|
}
|
|
379
399
|
}
|
|
400
|
+
function appendToShellProfile(profile, lines) {
|
|
401
|
+
const block = [
|
|
402
|
+
"",
|
|
403
|
+
"# Liminal \u2014 route AI tools through compression proxy",
|
|
404
|
+
...lines
|
|
405
|
+
].join("\n") + "\n";
|
|
406
|
+
appendFileSync(profile.path, block, "utf-8");
|
|
407
|
+
}
|
|
380
408
|
async function initCommand() {
|
|
381
409
|
printBanner();
|
|
382
410
|
console.log(" Welcome to Liminal -- Your Transparency & Context Partner");
|
|
@@ -406,10 +434,10 @@ async function initCommand() {
|
|
|
406
434
|
const toolsResult = await multiSelectPrompt({
|
|
407
435
|
message: "Which AI tools will you use with Liminal?",
|
|
408
436
|
options: [
|
|
409
|
-
{ label: "Claude Code", value: "claude-code",
|
|
410
|
-
{ label: "Codex", value: "codex"
|
|
411
|
-
{ label: "Cursor", value: "cursor"
|
|
412
|
-
{ label: "Other / OpenAI", value: "openai-compatible"
|
|
437
|
+
{ label: "Claude Code", value: "claude-code", default: true },
|
|
438
|
+
{ label: "Codex", value: "codex" },
|
|
439
|
+
{ label: "Cursor", value: "cursor" },
|
|
440
|
+
{ label: "Other / OpenAI", value: "openai-compatible" }
|
|
413
441
|
]
|
|
414
442
|
});
|
|
415
443
|
const tools = toolsResult ?? ["claude-code"];
|
|
@@ -462,13 +490,61 @@ async function initCommand() {
|
|
|
462
490
|
console.log();
|
|
463
491
|
console.log(` Configuration saved to ${CONFIG_FILE}`);
|
|
464
492
|
console.log();
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
493
|
+
const exportLines = getExportLines(tools, port);
|
|
494
|
+
const hasCursor = tools.includes("cursor");
|
|
495
|
+
if (exportLines.length > 0) {
|
|
496
|
+
const profile = detectShellProfile();
|
|
497
|
+
if (profile) {
|
|
498
|
+
const allExist = exportLines.every((line) => lineExistsInFile(profile.path, line));
|
|
499
|
+
if (allExist) {
|
|
500
|
+
console.log(` Shell already configured in ${profile.name}`);
|
|
501
|
+
} else {
|
|
502
|
+
const autoResult = await selectPrompt({
|
|
503
|
+
message: "Configure shell automatically?",
|
|
504
|
+
options: [
|
|
505
|
+
{ label: "Yes", value: true, description: `Add to ${profile.name}` },
|
|
506
|
+
{ label: "No", value: false, description: "I'll set it up manually" }
|
|
507
|
+
],
|
|
508
|
+
defaultIndex: 0
|
|
509
|
+
});
|
|
510
|
+
if (autoResult === true) {
|
|
511
|
+
const newLines = exportLines.filter((line) => !lineExistsInFile(profile.path, line));
|
|
512
|
+
if (newLines.length > 0) {
|
|
513
|
+
appendToShellProfile(profile, newLines);
|
|
514
|
+
}
|
|
515
|
+
console.log();
|
|
516
|
+
console.log(` Added to ${profile.name}:`);
|
|
517
|
+
for (const line of exportLines) {
|
|
518
|
+
console.log(` ${line}`);
|
|
519
|
+
}
|
|
520
|
+
console.log();
|
|
521
|
+
console.log(` Run \x1B[1msource ${profile.name}\x1B[0m or restart your terminal to apply.`);
|
|
522
|
+
} else {
|
|
523
|
+
console.log();
|
|
524
|
+
console.log(" Add these to your shell profile:");
|
|
525
|
+
console.log();
|
|
526
|
+
for (const line of exportLines) {
|
|
527
|
+
console.log(` ${line}`);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} else {
|
|
532
|
+
console.log(" Add these to your shell profile:");
|
|
533
|
+
console.log();
|
|
534
|
+
for (const line of exportLines) {
|
|
535
|
+
console.log(` ${line}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
471
538
|
}
|
|
539
|
+
if (hasCursor) {
|
|
540
|
+
console.log();
|
|
541
|
+
console.log(" Cursor setup (manual):");
|
|
542
|
+
console.log(` Settings > Models > OpenAI API Base URL: http://127.0.0.1:${port}/v1`);
|
|
543
|
+
}
|
|
544
|
+
console.log();
|
|
545
|
+
console.log(" Next step:");
|
|
546
|
+
console.log(" liminal start");
|
|
547
|
+
console.log();
|
|
472
548
|
}
|
|
473
549
|
|
|
474
550
|
// src/rsc/pipeline.ts
|
|
@@ -1131,7 +1207,7 @@ var ProxyServer = class {
|
|
|
1131
1207
|
};
|
|
1132
1208
|
|
|
1133
1209
|
// src/daemon/logger.ts
|
|
1134
|
-
import { appendFileSync, statSync, renameSync, mkdirSync as mkdirSync2, existsSync as
|
|
1210
|
+
import { appendFileSync as appendFileSync2, statSync, renameSync, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
|
|
1135
1211
|
import { dirname as dirname2 } from "path";
|
|
1136
1212
|
var MAX_LOG_SIZE = 10 * 1024 * 1024;
|
|
1137
1213
|
var MAX_BACKUPS = 2;
|
|
@@ -1142,7 +1218,7 @@ var FileLogger = class {
|
|
|
1142
1218
|
this.logFile = options?.logFile ?? LOG_FILE;
|
|
1143
1219
|
this.mirrorStdout = options?.mirrorStdout ?? false;
|
|
1144
1220
|
const logDir = dirname2(this.logFile);
|
|
1145
|
-
if (!
|
|
1221
|
+
if (!existsSync3(logDir)) {
|
|
1146
1222
|
mkdirSync2(logDir, { recursive: true });
|
|
1147
1223
|
}
|
|
1148
1224
|
}
|
|
@@ -1151,7 +1227,7 @@ var FileLogger = class {
|
|
|
1151
1227
|
const line = `[${timestamp}] ${message}
|
|
1152
1228
|
`;
|
|
1153
1229
|
try {
|
|
1154
|
-
|
|
1230
|
+
appendFileSync2(this.logFile, line);
|
|
1155
1231
|
} catch {
|
|
1156
1232
|
process.stderr.write(`[LOG-WRITE-FAILED] ${line}`);
|
|
1157
1233
|
}
|
|
@@ -1167,7 +1243,7 @@ var FileLogger = class {
|
|
|
1167
1243
|
for (let i = MAX_BACKUPS - 1; i >= 1; i--) {
|
|
1168
1244
|
const from = `${this.logFile}.${i}`;
|
|
1169
1245
|
const to = `${this.logFile}.${i + 1}`;
|
|
1170
|
-
if (
|
|
1246
|
+
if (existsSync3(from)) renameSync(from, to);
|
|
1171
1247
|
}
|
|
1172
1248
|
renameSync(this.logFile, `${this.logFile}.1`);
|
|
1173
1249
|
} catch {
|
|
@@ -1179,16 +1255,16 @@ var FileLogger = class {
|
|
|
1179
1255
|
};
|
|
1180
1256
|
|
|
1181
1257
|
// src/daemon/lifecycle.ts
|
|
1182
|
-
import { readFileSync as
|
|
1258
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync, existsSync as existsSync4 } from "fs";
|
|
1183
1259
|
import { fork } from "child_process";
|
|
1184
1260
|
import { fileURLToPath } from "url";
|
|
1185
1261
|
function writePidFile(pid) {
|
|
1186
1262
|
writeFileSync2(PID_FILE, String(pid), "utf-8");
|
|
1187
1263
|
}
|
|
1188
1264
|
function readPidFile() {
|
|
1189
|
-
if (!
|
|
1265
|
+
if (!existsSync4(PID_FILE)) return null;
|
|
1190
1266
|
try {
|
|
1191
|
-
const content =
|
|
1267
|
+
const content = readFileSync3(PID_FILE, "utf-8").trim();
|
|
1192
1268
|
const pid = parseInt(content, 10);
|
|
1193
1269
|
return isNaN(pid) ? null : pid;
|
|
1194
1270
|
} catch {
|
|
@@ -1197,7 +1273,7 @@ function readPidFile() {
|
|
|
1197
1273
|
}
|
|
1198
1274
|
function removePidFile() {
|
|
1199
1275
|
try {
|
|
1200
|
-
if (
|
|
1276
|
+
if (existsSync4(PID_FILE)) unlinkSync(PID_FILE);
|
|
1201
1277
|
} catch {
|
|
1202
1278
|
}
|
|
1203
1279
|
}
|
|
@@ -1578,17 +1654,17 @@ async function configCommand(flags) {
|
|
|
1578
1654
|
}
|
|
1579
1655
|
|
|
1580
1656
|
// src/commands/logs.ts
|
|
1581
|
-
import { readFileSync as
|
|
1657
|
+
import { readFileSync as readFileSync4, existsSync as existsSync5, statSync as statSync2, createReadStream } from "fs";
|
|
1582
1658
|
import { watchFile, unwatchFile } from "fs";
|
|
1583
1659
|
async function logsCommand(flags) {
|
|
1584
1660
|
const follow = flags.has("follow") || flags.has("f");
|
|
1585
1661
|
const linesFlag = flags.get("lines") ?? flags.get("n");
|
|
1586
1662
|
const lines = typeof linesFlag === "string" ? parseInt(linesFlag, 10) : 50;
|
|
1587
|
-
if (!
|
|
1663
|
+
if (!existsSync5(LOG_FILE)) {
|
|
1588
1664
|
console.log('No log file found. Start the daemon with "liminal start" to generate logs.');
|
|
1589
1665
|
return;
|
|
1590
1666
|
}
|
|
1591
|
-
const content =
|
|
1667
|
+
const content = readFileSync4(LOG_FILE, "utf-8");
|
|
1592
1668
|
const allLines = content.split("\n");
|
|
1593
1669
|
const tail = allLines.slice(-lines - 1);
|
|
1594
1670
|
process.stdout.write(tail.join("\n"));
|
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/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.0'\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 { RSCTransport, CircuitBreaker } from '@cognisos/rsc-sdk'\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 type { Tool } from '../types.js'\n\nfunction printToolInstructions(tool: Tool, port: number): void {\n const base = `http://127.0.0.1:${port}`\n switch (tool) {\n case 'claude-code':\n console.log(' Claude Code:')\n console.log(` export ANTHROPIC_BASE_URL=${base}`)\n console.log(' (Add to your shell profile for persistence)')\n console.log()\n break\n case 'codex':\n console.log(' Codex:')\n console.log(` export OPENAI_BASE_URL=${base}/v1`)\n console.log(' (Add to your shell profile for persistence)')\n console.log()\n break\n case 'cursor':\n console.log(' Cursor:')\n console.log(` Settings > Models > OpenAI API Base URL: ${base}/v1`)\n console.log()\n break\n case 'openai-compatible':\n console.log(' OpenAI-compatible tools:')\n console.log(` Set your base URL to: ${base}/v1`)\n console.log()\n break\n }\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 // ── Text inputs (readline) ──────────────────────────────────────\n const rl = createInterface({ input: stdin, output: stdout })\n let apiKey: string\n let port: number\n\n try {\n const apiKeyInput = await rl.question(' \\x1b[1mLiminal API key\\x1b[0m: ')\n if (!apiKeyInput.trim()) {\n console.error('\\n Error: API key is required.')\n process.exit(1)\n }\n apiKey = apiKeyInput.trim()\n\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', description: 'export ANTHROPIC_BASE_URL=...', default: true },\n { label: 'Codex', value: 'codex', description: 'export OPENAI_BASE_URL=...' },\n { label: 'Cursor', value: 'cursor', description: 'Settings > Models > Base URL' },\n { label: 'Other / OpenAI', value: 'openai-compatible', description: 'Set base URL manually' },\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 // ── Validate API key ────────────────────────────────────────────\n const apiBaseUrl = DEFAULTS.apiBaseUrl\n process.stdout.write(' Validating API key... ')\n try {\n const breaker = new CircuitBreaker(3, 10_000)\n const transport = new RSCTransport({\n baseUrl: apiBaseUrl,\n apiKey,\n timeout: 10_000,\n maxRetries: 1,\n circuitBreaker: breaker,\n })\n await transport.get<{ status: string }>('/health')\n console.log('OK')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.log('FAILED')\n console.error(`\\n Could not connect to Liminal API: ${message}`)\n console.error(' Check your API key and URL, then try again.')\n process.exit(1)\n }\n\n // ── Save config ─────────────────────────────────────────────────\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 console.log(' Next steps:')\n console.log(' 1. Start the proxy: liminal start')\n console.log(' 2. Connect your tools:')\n console.log()\n\n for (const tool of tools) {\n printToolInstructions(tool, port)\n }\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: '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 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","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\nfunction extractAnthropicApiKey(req: http.IncomingMessage): string | null {\n const key = req.headers['x-api-key']\n if (typeof key === 'string' && key.length > 0) return key\n return null\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 API key from x-api-key header\n const apiKey = extractAnthropicApiKey(req)\n if (!apiKey) {\n sendAnthropicError(res, 401, 'authentication_error', 'x-api-key header is required')\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 'x-api-key': apiKey,\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 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 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\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 url = req.url ?? ''\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 // 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 { 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 (API key, config)\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 # Enter your API key + 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 '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":["stdin","stdout","RSCTransport","CircuitBreaker","RSCCircuitOpenError","RSCCircuitOpenError","RSCCircuitOpenError","setCORSHeaders","RSCCircuitOpenError","setCORSHeaders","sendJSON","mkdirSync","existsSync","dirname","dirname","existsSync","mkdirSync","readFileSync","writeFileSync","existsSync","writeFileSync","existsSync","readFileSync","formatUptime","config","readFileSync","existsSync","statSync","existsSync","readFileSync","statSync"]}
|
|
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/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 { RSCTransport, CircuitBreaker } from '@cognisos/rsc-sdk'\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 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 // ── Text inputs (readline) ──────────────────────────────────────\n const rl = createInterface({ input: stdin, output: stdout })\n let apiKey: string\n let port: number\n\n try {\n const apiKeyInput = await rl.question(' \\x1b[1mLiminal API key\\x1b[0m: ')\n if (!apiKeyInput.trim()) {\n console.error('\\n Error: API key is required.')\n process.exit(1)\n }\n apiKey = apiKeyInput.trim()\n\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 // ── Validate API key ────────────────────────────────────────────\n const apiBaseUrl = DEFAULTS.apiBaseUrl\n process.stdout.write(' Validating API key... ')\n try {\n const breaker = new CircuitBreaker(3, 10_000)\n const transport = new RSCTransport({\n baseUrl: apiBaseUrl,\n apiKey,\n timeout: 10_000,\n maxRetries: 1,\n circuitBreaker: breaker,\n })\n await transport.get<{ status: string }>('/health')\n console.log('OK')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n console.log('FAILED')\n console.error(`\\n Could not connect to Liminal API: ${message}`)\n console.error(' Check your API key and URL, then try again.')\n process.exit(1)\n }\n\n // ── Save config ─────────────────────────────────────────────────\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: '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 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","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\nfunction extractAnthropicApiKey(req: http.IncomingMessage): string | null {\n const key = req.headers['x-api-key']\n if (typeof key === 'string' && key.length > 0) return key\n return null\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 API key from x-api-key header\n const apiKey = extractAnthropicApiKey(req)\n if (!apiKey) {\n sendAnthropicError(res, 401, 'authentication_error', 'x-api-key header is required')\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 'x-api-key': apiKey,\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 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 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\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 url = req.url ?? ''\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 // 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 { 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 (API key, config)\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 # Enter your API key + 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 '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":["existsSync","readFileSync","join","homedir","stdin","stdout","homedir","join","existsSync","readFileSync","RSCTransport","CircuitBreaker","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"]}
|