diff --git a/.omc/project-memory.json b/.omc/project-memory.json deleted file mode 100644 index 7018fa00e1..0000000000 --- a/.omc/project-memory.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "version": "1.0.0", - "lastScanned": 1775016362438, - "projectRoot": "/home/openclaw/omniroute-src", - "techStack": { - "languages": [ - { - "name": "JavaScript/TypeScript", - "version": ">=18.0.0 <24.0.0", - "confidence": "high", - "markers": ["package.json"] - }, - { - "name": "TypeScript", - "version": null, - "confidence": "high", - "markers": ["tsconfig.json"] - } - ], - "frameworks": [ - { - "name": "express", - "version": "5.2.1", - "category": "backend" - }, - { - "name": "next", - "version": "16.0.10", - "category": "fullstack" - }, - { - "name": "react", - "version": "19.2.4", - "category": "frontend" - }, - { - "name": "react-dom", - "version": "19.2.4", - "category": "frontend" - }, - { - "name": "@playwright/test", - "version": "1.58.2", - "category": "testing" - }, - { - "name": "vitest", - "version": "4.0.18", - "category": "testing" - } - ], - "packageManager": "npm", - "runtime": "Node.js 18.0.024.0.0" - }, - "build": { - "buildCommand": "npm run build", - "testCommand": "npm test", - "lintCommand": "npm run lint", - "devCommand": "npm run dev", - "scripts": { - "dev": "node scripts/run-next.mjs dev", - "build": "node scripts/build-next-isolated.mjs", - "build:cli": "node scripts/prepublish.mjs", - "start": "node scripts/run-next.mjs start", - "lint": "eslint .", - "electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:20128 && cd electron && npm run dev\"", - "electron:build": "npm run build && cd electron && npm run build", - "electron:build:win": "npm run build && cd electron && npm run build:win", - "electron:build:mac": "npm run build && cd electron && npm run build:mac", - "electron:build:linux": "npm run build && cd electron && npm run build:linux", - "test": "node --import tsx/esm --test tests/unit/*.test.mjs", - "test:unit": "node --import tsx/esm --test tests/unit/*.test.mjs", - "test:plan3": "node --import tsx/esm --test tests/unit/plan3-p0.test.mjs", - "test:fixes": "node --import tsx/esm --test tests/unit/fixes-p1.test.mjs", - "test:security": "node --import tsx/esm --test tests/unit/security-fase01.test.mjs", - "check:cycles": "node scripts/check-cycles.mjs", - "check:route-validation:t06": "node scripts/check-route-validation.mjs", - "check:any-budget:t11": "node scripts/check-t11-any-budget.mjs", - "check:docs-sync": "node scripts/check-docs-sync.mjs", - "typecheck:core": "tsc --pretty false -p tsconfig.typecheck-core.json", - "typecheck:noimplicit:core": "tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json", - "test:integration": "node --import tsx/esm --test tests/integration/*.test.mjs", - "test:e2e": "node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts", - "test:protocols:e2e": "node scripts/run-protocol-clients-tests.mjs", - "test:vitest": "vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts", - "test:ecosystem": "node scripts/run-ecosystem-tests.mjs", - "test:coverage": "c8 --exclude=tests/** --exclude=**/*.test.* --reporter=text-summary --reporter=html --reporter=json-summary --reporter=lcov --check-coverage --statements 55 --lines 55 --functions 55 --branches 60 node --import tsx/esm --test tests/unit/*.test.mjs", - "test:coverage:legacy": "c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs", - "coverage:report": "c8 report --exclude=tests/** --exclude=**/*.test.* --reporter=text --reporter=text-summary --reporter=html --reporter=json-summary --reporter=lcov", - "coverage:report:legacy": "c8 report --exclude=open-sse --reporter=text --reporter=text-summary", - "test:all": "npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e", - "check": "npm run lint && npm run test", - "prepublishOnly": "npm run build:cli", - "postinstall": "node scripts/postinstall.mjs", - "prepare": "husky", - "system-info": "node scripts/system-info.mjs" - } - }, - "conventions": { - "namingStyle": "camelCase", - "importStyle": null, - "testPattern": null, - "fileOrganization": null - }, - "structure": { - "isMonorepo": true, - "workspaces": ["open-sse"], - "mainDirectories": ["bin", "docs", "public", "scripts", "src", "tests"], - "gitBranches": { - "defaultBranch": "main", - "branchingStrategy": null - } - }, - "customNotes": [], - "directoryMap": { - "bin": { - "path": "bin", - "purpose": "Executable scripts", - "fileCount": 3, - "lastAccessed": 1775016362426, - "keyFiles": ["mcp-server.mjs", "omniroute.mjs", "reset-password.mjs"] - }, - "docs": { - "path": "docs", - "purpose": "Documentation", - "fileCount": 14, - "lastAccessed": 1775016362426, - "keyFiles": [ - "A2A-SERVER.md", - "API_REFERENCE.md", - "ARCHITECTURE.md", - "AUTO-COMBO.md", - "CLI-TOOLS.md" - ] - }, - "electron": { - "path": "electron", - "purpose": null, - "fileCount": 5, - "lastAccessed": 1775016362431, - "keyFiles": ["README.md", "main.js", "package.json", "preload.js", "types.d.ts"] - }, - "images": { - "path": "images", - "purpose": null, - "fileCount": 1, - "lastAccessed": 1775016362434, - "keyFiles": ["omniroute.png"] - }, - "logs": { - "path": "logs", - "purpose": null, - "fileCount": 3, - "lastAccessed": 1775016362434, - "keyFiles": ["build_clean_tools.log", "build_debug.log", "build_force_clean.log"] - }, - "open-sse": { - "path": "open-sse", - "purpose": null, - "fileCount": 5, - "lastAccessed": 1775016362434, - "keyFiles": ["index.ts", "package.json", "tsconfig.json", "types.d.ts"] - }, - "public": { - "path": "public", - "purpose": "Public files", - "fileCount": 3, - "lastAccessed": 1775016362435, - "keyFiles": ["apple-touch-icon.svg", "favicon.svg", "icon-192.svg"] - }, - "scripts": { - "path": "scripts", - "purpose": "Build/utility scripts", - "fileCount": 23, - "lastAccessed": 1775016362435, - "keyFiles": [ - "bootstrap-env.mjs", - "build-next-isolated.mjs", - "check-cycles.mjs", - "check-docs-sync.mjs", - "check-route-validation.mjs" - ] - }, - "src": { - "path": "src", - "purpose": "Source code", - "fileCount": 4, - "lastAccessed": 1775016362435, - "keyFiles": ["instrumentation-node.ts", "instrumentation.ts", "proxy.ts", "server-init.ts"] - }, - "tests": { - "path": "tests", - "purpose": "Test files", - "fileCount": 0, - "lastAccessed": 1775016362435, - "keyFiles": [] - }, - "electron/assets": { - "path": "electron/assets", - "purpose": "Static assets", - "fileCount": 4, - "lastAccessed": 1775016362436, - "keyFiles": ["icon.icns", "icon.ico", "icon.png"] - }, - "open-sse/config": { - "path": "open-sse/config", - "purpose": "Configuration files", - "fileCount": 17, - "lastAccessed": 1775016362436, - "keyFiles": ["audioRegistry.ts", "cliFingerprints.ts", "codexInstructions.ts"] - }, - "open-sse/services": { - "path": "open-sse/services", - "purpose": "Business logic services", - "fileCount": 35, - "lastAccessed": 1775016362437, - "keyFiles": ["accountFallback.ts", "accountSelector.ts", "apiKeyRotator.ts"] - }, - "src/app": { - "path": "src/app", - "purpose": "Application code", - "fileCount": 7, - "lastAccessed": 1775016362438, - "keyFiles": ["error.tsx", "global-error.tsx", "globals.css"] - }, - "src/lib": { - "path": "src/lib", - "purpose": "Library code", - "fileCount": 30, - "lastAccessed": 1775016362438, - "keyFiles": ["apiBridgeServer.ts", "apiKeyExposure.ts", "cacheControlSettings.ts"] - }, - "src/middleware": { - "path": "src/middleware", - "purpose": "Middleware", - "fileCount": 1, - "lastAccessed": 1775016362438, - "keyFiles": ["promptInjectionGuard.ts"] - }, - "src/models": { - "path": "src/models", - "purpose": "Data models", - "fileCount": 1, - "lastAccessed": 1775016362438, - "keyFiles": ["index.ts"] - } - }, - "hotPaths": [], - "userDirectives": [] -} diff --git a/.omc/sessions/53c002c3-36a6-47c3-a52d-a8f756c264eb.json b/.omc/sessions/53c002c3-36a6-47c3-a52d-a8f756c264eb.json deleted file mode 100644 index f3dfd0f299..0000000000 --- a/.omc/sessions/53c002c3-36a6-47c3-a52d-a8f756c264eb.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "session_id": "53c002c3-36a6-47c3-a52d-a8f756c264eb", - "ended_at": "2026-04-01T04:06:04.924Z", - "reason": "prompt_input_exit", - "agents_spawned": 0, - "agents_completed": 0, - "modes_used": [] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index fae48f28c7..442a2bedab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,33 @@ "level": "off" } }, - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + // "files.exclude": { + // "**/_references": true, + // "**/_mono_repo": true, + // "**/electron": true, + // "**/node_modules": true, + // "**/.next": true, + // "**/coverage": true, + // "**/omniroute-*.tgz": true, + // "**/_tasks": true + // }, + "files.watcherExclude": { + "**/_references/**": true, + "**/_mono_repo/**": true, + "**/electron/**": true, + "**/node_modules/**": true, + "**/.next/**": true, + "**/coverage/**": true, + "**/_tasks/**": true + }, + "search.exclude": { + "**/_references": true, + "**/_mono_repo": true, + "**/electron": true, + "**/node_modules": true, + "**/.next": true, + "**/coverage": true, + "**/_tasks": true + } } diff --git a/next.config.mjs b/next.config.mjs deleted file mode 100644 index 79348ec773..0000000000 --- a/next.config.mjs +++ /dev/null @@ -1,231 +0,0 @@ -import createNextIntlPlugin from "next-intl/plugin"; -import { dirname } from "node:path"; -import { fileURLToPath } from "node:url"; - -const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts"); -const distDir = process.env.NEXT_DIST_DIR || ".next"; -const projectRoot = dirname(fileURLToPath(import.meta.url)); - -/** @type {import('next').NextConfig} */ -const nextConfig = { - distDir, - // Turbopack config: redirect native modules to stubs at build time - turbopack: { - root: projectRoot, - resolveAlias: { - // Point mitm/manager to a stub during build (native child_process/fs can't be bundled) - "@/mitm/manager": "./src/mitm/manager.stub.ts", - }, - }, - output: "standalone", - // OmniRoute is a proxy for AI APIs — request bodies routinely include - // multi-MB payloads (vision models, image edits, base64-encoded files, - // long chat histories with embedded images). Next.js's Server Action - // handler intercepts POSTs with multipart/form-data or - // x-www-form-urlencoded content-types and enforces a 1 MB cap that - // surfaces as a 413 with a confusing "Server Actions" hint, even on - // pure route handlers. 50 MB matches what most upstream LLM providers - // accept for image-bearing requests; tune via env if a deployment needs - // more. - experimental: { - serverActions: { - bodySizeLimit: process.env.OMNIROUTE_SERVER_ACTIONS_BODY_LIMIT || "50mb", - }, - }, - outputFileTracingRoot: projectRoot, - outputFileTracingIncludes: { - // Migration SQL files are read via fs.readFileSync at runtime and are NOT - // auto-traced by webpack/turbopack — include them explicitly. - "/*": ["./src/lib/db/migrations/**/*"], - }, - outputFileTracingExcludes: { - // Planning/task docs are not runtime assets and can break standalone copies - // when broad fs/path tracing pulls the whole repository into the NFT graph. - "/*": [ - "./.git/**/*", - "./_tasks/**/*", - "./_references/**/*", - "./_ideia/**/*", - "./_mono_repo/**/*", - "./coverage/**/*", - "./test-results/**/*", - "./playwright-report/**/*", - "./app.__qa_backup/**/*", - "./tests/**/*", - "./logs/**/*", - ], - }, - serverExternalPackages: [ - "pino", - "pino-pretty", - "thread-stream", - "pino-abstract-transport", - "better-sqlite3", - "keytar", - "wreq-js", - "zod", - "tls-client-node", - "koffi", - "tough-cookie", - "@ngrok/ngrok", - "child_process", - "fs", - "path", - "os", - "crypto", - "net", - "tls", - "http", - "https", - "stream", - "buffer", - "util", - "process", - ], - transpilePackages: ["@omniroute/open-sse", "@lobehub/icons"], - allowedDevOrigins: ["localhost", "127.0.0.1", "192.168.*"], - typescript: { - // TODO: Re-enable after fixing all sub-component useTranslations scope issues - ignoreBuildErrors: true, - }, - images: { - unoptimized: true, - }, - webpack: (config, { isServer, webpack }) => { - if (isServer) { - // Webpack IgnorePlugin: skip thread-stream test files that contain - // intentionally broken syntax/imports (they cause Turbopack build errors) - config.plugins.push( - new webpack.IgnorePlugin({ - resourceRegExp: /\/test\//, - contextRegExp: /thread-stream/, - }) - ); - - // Mark @ngrok/ngrok as external to prevent webpack from trying to bundle its .node binaries - config.externals = config.externals || []; - config.externals.push({ - "@ngrok/ngrok": "commonjs @ngrok/ngrok", - }); - // ── Turbopack / Next.js 16 module-hash patch (#394, #396, #398) ──────── - // - // Next.js 16 (with or without Turbopack) compiles the instrumentation hook - // into a separate chunk and emits hashed require() calls such as: - // require('better-sqlite3-90e2652d1716b047') - // require('zod-dcb22c6336e0bc69') - // require('pino-28069d5257187539') - // - // These hashed names don't exist in node_modules and cause a 500 at - // startup on all npm global installs (issues #394, #396, #398). - // - // We use two strategies: - // 1. Exact-name externals for all known server-side packages. - // 2. Hash-strip catch-all: any require('-<16hexchars>[/subpath]') - // strips the hash suffix and falls through to the real package name. - // - const HASH_PATTERN = /^(.+)-[0-9a-f]{16}(\/.*)?$/; - - const KNOWN_EXTERNALS = new Set([ - "better-sqlite3", - "keytar", - "wreq-js", - "zod", - "pino", - "pino-pretty", - "pino-abstract-transport", - "child_process", - "fs", - "path", - "os", - "crypto", - "net", - "tls", - "http", - "https", - "stream", - "buffer", - "util", - "process", - ]); - - const prev = config.externals ?? []; - const prevArr = Array.isArray(prev) ? prev : [prev]; - config.externals = [ - ...prevArr, - ({ request }, callback) => { - // Case 1: Exact known package — treat as external - if (KNOWN_EXTERNALS.has(request)) { - return callback(null, `commonjs ${request}`); - } - // Case 2: Hash-suffixed name — strip hash, preserve subpath - // e.g. "better-sqlite3-90e2652d1716b047" → "better-sqlite3" - // "zod-dcb22c6336e0bc69" → "zod" - // "zod-dcb22c6336e0bc69/v3" → "zod/v3" - // "zod-dcb22c6336e0bc69/v4-mini" → "zod/v4-mini" - const hashMatch = request?.match?.(HASH_PATTERN); - if (hashMatch) { - const resolved = hashMatch[2] ? `${hashMatch[1]}${hashMatch[2]}` : hashMatch[1]; - return callback(null, `commonjs ${resolved}`); - } - callback(); - }, - ]; - } else { - // Ignore native Node.js modules in browser bundle - config.resolve.fallback = { - ...config.resolve.fallback, - fs: false, - path: false, - child_process: false, - net: false, - tls: false, - crypto: false, - process: false, - }; - } - return config; - }, - - async rewrites() { - return [ - { - source: "/chat/completions", - destination: "/api/v1/chat/completions", - }, - { - source: "/responses", - destination: "/api/v1/responses", - }, - { - source: "/responses/:path*", - destination: "/api/v1/responses/:path*", - }, - { - source: "/models", - destination: "/api/v1/models", - }, - { - source: "/v1/v1/:path*", - destination: "/api/v1/:path*", - }, - { - source: "/v1/v1", - destination: "/api/v1", - }, - { - source: "/codex/:path*", - destination: "/api/v1/responses", - }, - { - source: "/v1/:path*", - destination: "/api/v1/:path*", - }, - { - source: "/v1", - destination: "/api/v1", - }, - ]; - }, -}; - -export default withNextIntl(nextConfig); diff --git a/patch.js b/patch.js deleted file mode 100644 index 76d67dfa55..0000000000 --- a/patch.js +++ /dev/null @@ -1,21 +0,0 @@ -const fs = require("fs"); -let file = fs.readFileSync("tests/unit/reasoning-cache.test.ts", "utf8"); - -// Insert import for updateSettings -if (!file.includes("updateSettings")) { - file = file.replace( - "import { getDbInstance }", - 'import { getDbInstance } from "../../src/lib/db/core.ts";\nimport { updateSettings, getSettings } from "../../src/lib/db/settings.ts";\n// import { getDbInstance }' - ); -} - -// Add DB update logic -file = file.replace( - 'process.env.REQUIRE_LOGIN = "false";', - 'process.env.REQUIRE_LOGIN = "false";\n await updateSettings({ requireLogin: false });' -); - -// We need to make `before()` async -file = file.replace(" before(() => {", " before(async () => {"); - -fs.writeFileSync("tests/unit/reasoning-cache.test.ts", file); diff --git a/patch2.js b/patch2.js deleted file mode 100644 index 6dc61783b3..0000000000 --- a/patch2.js +++ /dev/null @@ -1,35 +0,0 @@ -const fs = require("fs"); -let file = fs.readFileSync("tests/unit/reasoning-cache.test.ts", "utf8"); - -// Replace the before/after blocks -file = file.replace( - /describe\("Reasoning Replay Cache — API Route", \(\) => {[\s\S]*?(?= it\("should return stats)/m, - `describe("Reasoning Replay Cache — API Route", () => { - before(() => { - clearReasoningCacheAll(); - try { - getDbInstance().prepare( - "INSERT OR IGNORE INTO api_keys (key, name, role, is_active) VALUES ('test-admin-key', 'test', 'admin', 1)" - ).run(); - } catch (e) {} - }); - - after(() => { - clearReasoningCacheAll(); - try { - getDbInstance().prepare("DELETE FROM api_keys WHERE key = 'test-admin-key'").run(); - } catch (e) {} - });\n\n` -); - -// Add Headers -file = file.replace( - /new Request\("http:\/\/localhost\/api\/cache\/reasoning\?provider=deepseek"\)/g, - 'new Request("http://localhost/api/cache/reasoning?provider=deepseek", { headers: { Authorization: "Bearer test-admin-key" } })' -); -file = file.replace( - /new Request\("http:\/\/localhost\/api\/cache\/reasoning\?toolCallId=call_api_delete_1"\)/g, - 'new Request("http://localhost/api/cache/reasoning?toolCallId=call_api_delete_1", { headers: { Authorization: "Bearer test-admin-key" } })' -); - -fs.writeFileSync("tests/unit/reasoning-cache.test.ts", file); diff --git a/patch3.js b/patch3.js deleted file mode 100644 index 05b1bf9e59..0000000000 --- a/patch3.js +++ /dev/null @@ -1,43 +0,0 @@ -const fs = require("fs"); -let file = fs.readFileSync("tests/unit/reasoning-cache.test.ts", "utf8"); - -file = file.replace( - /describe\("Reasoning Replay Cache — API Route", \(\) => \{[\s\S]*?(?= it\("should return stats)/m, - `describe("Reasoning Replay Cache — API Route", () => { - let originalInitialPassword; - let originalRequireLogin; - - before(async () => { - clearReasoningCacheAll(); - originalInitialPassword = process.env.INITIAL_PASSWORD; - originalRequireLogin = process.env.REQUIRE_LOGIN; - process.env.INITIAL_PASSWORD = ""; - process.env.REQUIRE_LOGIN = "false"; - - try { - const { getDbInstance } = await import("../../src/lib/db/core.ts"); - getDbInstance().prepare( - "INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES ('settings', 'requireLogin', 'false')" - ).run(); - getDbInstance().prepare( - "DELETE FROM key_value WHERE namespace = 'settings' AND key = 'password'" - ).run(); - } catch (e) {} - }); - - after(async () => { - clearReasoningCacheAll(); - process.env.INITIAL_PASSWORD = originalInitialPassword; - process.env.REQUIRE_LOGIN = originalRequireLogin; - try { - const { getDbInstance } = await import("../../src/lib/db/core.ts"); - getDbInstance().prepare( - "INSERT OR REPLACE INTO key_value (namespace, key, value) VALUES ('settings', 'requireLogin', 'true')" - ).run(); - } catch (e) {} - });\n\n` -); - -file = file.replace(/, \{ headers: \{ Authorization: "Bearer test-admin-key" \} \}/g, ""); - -fs.writeFileSync("tests/unit/reasoning-cache.test.ts", file); diff --git a/tsconfig.json b/tsconfig.json index 63a91d7204..2a04942a4d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -45,6 +45,10 @@ "antigravity-manager-analysis", "app.__qa_backup", "vscode-extension", + "vs_ideia", + "_tasks", + "_mono_repo", + "_references", "omnirouteCloud", "omnirouteSite" ]