mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 10:12:11 +03:00
Compare commits
2 Commits
v3.0.0-rc.
...
v3.0.0-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ea73bd527 | ||
|
|
b2f0820560 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -6,16 +6,24 @@
|
||||
|
||||
---
|
||||
|
||||
## [3.0.0-rc.13] — 2026-03-23
|
||||
|
||||
### 🔧 Bug Fixes
|
||||
|
||||
- **config:** resolve real API key from `keyId` in CLI settings routes (`codex-settings`, `droid-settings`, `kilo-settings`) to prevent writing masked strings (#549)
|
||||
|
||||
---
|
||||
|
||||
## [3.0.0-rc.12] — 2026-03-23
|
||||
|
||||
### 🔀 Community PRs Merged
|
||||
|
||||
| PR | Author | Summary |
|
||||
| -------- | -------- | --------------------------------------------------------------------------------- |
|
||||
| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows — use `JSON.parse(readFileSync)` instead of ESM import |
|
||||
| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution in credentials, autoCombo, responses logger, and request logger |
|
||||
| PR | Author | Summary |
|
||||
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows — use `JSON.parse(readFileSync)` instead of ESM import |
|
||||
| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution in credentials, autoCombo, responses logger, and request logger |
|
||||
| **#544** | @k0valik | fix(cli): secure CLI tool detection via known installation paths (8 tools) with symlink validation, file-type checks, size bounds, minimal env in healthcheck |
|
||||
| **#542** | @rdself | fix(ui): improve light mode contrast — add missing CSS theme variables (`bg-primary`, `bg-subtle`, `text-primary`) and fix dark-only colors in log detail |
|
||||
| **#542** | @rdself | fix(ui): improve light mode contrast — add missing CSS theme variables (`bg-primary`, `bg-subtle`, `text-primary`) and fix dark-only colors in log detail |
|
||||
|
||||
### 🔧 Bug Fixes
|
||||
|
||||
@@ -27,6 +35,7 @@
|
||||
- Test suite: **905 tests, 0 failures**
|
||||
|
||||
---
|
||||
|
||||
## [3.0.0-rc.10] — 2026-03-23
|
||||
|
||||
### 🔧 Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: OmniRoute API
|
||||
version: 3.0.0-rc.12
|
||||
version: 3.0.0-rc.13
|
||||
description: |
|
||||
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
|
||||
endpoint that routes requests to multiple AI providers with load balancing,
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "omniroute",
|
||||
"version": "3.0.0-rc.12",
|
||||
"version": "3.0.0-rc.13",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "omniroute",
|
||||
"version": "3.0.0-rc.12",
|
||||
"version": "3.0.0-rc.13",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "omniroute",
|
||||
"version": "3.0.0-rc.12",
|
||||
"version": "3.0.0-rc.13",
|
||||
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createMultiBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const getCodexConfigPath = () => getCliConfigPaths("codex").config;
|
||||
const getCodexAuthPath = () => getCliConfigPaths("codex").auth;
|
||||
@@ -166,7 +167,8 @@ export async function POST(request: Request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
if (!apiKey) {
|
||||
return NextResponse.json(
|
||||
{ error: "baseUrl, apiKey and model are required" },
|
||||
@@ -174,6 +176,21 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
// The dashboard sends masked key strings — resolving by ID guarantees
|
||||
// we always write the full key value to the config file.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
const codexDir = getCodexDir();
|
||||
const configPath = getCodexConfigPath();
|
||||
const authPath = getCodexAuthPath();
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const getDroidSettingsPath = () => getCliPrimaryConfigPath("droid");
|
||||
const getDroidDir = () => path.dirname(getDroidSettingsPath());
|
||||
@@ -101,7 +102,21 @@ export async function POST(request: Request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
const droidDir = getDroidDir();
|
||||
const settingsPath = getDroidSettingsPath();
|
||||
|
||||
@@ -9,6 +9,7 @@ import { createBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const KILO_DATA_DIR = path.join(os.homedir(), ".local", "share", "kilo");
|
||||
const AUTH_PATH = path.join(KILO_DATA_DIR, "auth.json");
|
||||
@@ -133,7 +134,21 @@ export async function POST(request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure directories exist
|
||||
await fs.mkdir(KILO_DATA_DIR, { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user