Skip to content

feat: support Bun bundled SQLite runtime - #7878

Merged
diegosouzapw merged 5 commits into
diegosouzapw:release/v3.8.49from
Arul-:codex/bun-sqlite-runtime
Jul 21, 2026
Merged

diegosouzapw merged 5 commits into
diegosouzapw:release/v3.8.49from
Arul-:codex/bun-sqlite-runtime

Conversation

@Arul-

@Arul- Arul- commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • use Bun's bundled bun:sqlite as the first synchronous SQLite driver
  • preserve better-sqlite3, node:sqlite, and sql.js fallback behavior
  • resolve sql-wasm.wasm from the installed package for global/Bun layouts
  • let the Bun CLI spawn the server with Bun instead of the node executable and incompatible V8 flags
  • make CLI setup/backup and OmniRoute credential storage work with Bun SQLite
  • add Bun CRUD, named-parameter, transaction, pragma, and close coverage

Why

A global Bun install can contain a valid OmniRoute runtime and sql.js, but the current serve preflight exits on the incompatible bundled better-sqlite3 binary before the existing fallback chain is reached. The fallback also assumed cwd/node_modules/sql.js, which is not true for Bun's global install layout.

Verification

  • bun test tests/unit/db-adapters/bunSqliteAdapter.test.ts tests/unit/db-adapters/nodeSqliteShared.test.ts passes
  • bun test tests/unit/db-adapters/driverFactory.test.ts passes with the installed sql.js package linked into the isolated checkout
  • direct Bun CRUD probe selects bun:sqlite
  • global-install sql.js probe successfully locates and loads sql-wasm.wasm
  • Bun syntax/import checks pass for the modified CLI modules

The full upstream suite was not run because this isolated checkout intentionally has no dependency tree installed; the repository currently declares Node as its supported engine.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for the native bun:sqlite driver when running under the Bun runtime, updating the database adapters, CLI helpers, and adding corresponding unit tests. The review feedback highlights several critical issues: first, bun:sqlite lacks a .prepare() method, meaning direct calls in src/lib/db/omp.ts will crash unless wrapped; second, using db.serialize() for backing up physical databases poses a significant out-of-memory risk and should be replaced with a standard checkpoint and file copy; and third, the parameter normalization in bin/cli/sqlite.mjs needs to explicitly skip Uint8Array and Buffer instances to prevent binary data corruption.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/lib/db/omp.ts
Comment on lines +6 to +12
const Database = process.versions.bun
? (_require("bun:sqlite").Database as typeof import("better-sqlite3"))
: (_require("better-sqlite3") as typeof import("better-sqlite3"));

function databaseOptions(readonly = false) {
return readonly ? { readonly: true } : { readwrite: true, create: true };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The bun:sqlite Database class does not have a .prepare() method (it uses .query()). Directly calling db.prepare(...) on a bun:sqlite instance will throw a runtime TypeError: db.prepare is not a function and crash the application under Bun. We should wrap the database instance when running under Bun to provide a compatible .prepare() method.

const Database = process.versions.bun
  ? _require("bun:sqlite").Database
  : _require("better-sqlite3");

function openDb(dbPath: string, readonly = false) {
  const opts = readonly ? { readonly: true } : { readwrite: true, create: true };
  const db = new Database(dbPath, opts);
  if (process.versions.bun) {
    return {
      prepare(sql: string) {
        const query = db.query(sql);
        return {
          get(...params: any[]) { return query.get(...params); },
          run(...params: any[]) { return query.run(...params); },
        };
      },
      close() { db.close(); }
    };
  }
  return db;
}

Comment thread src/lib/db/omp.ts
const dbPath = getOmpDbPath();
try {
const db = new Database(dbPath, { readonly: true });
const db = new Database(dbPath, databaseOptions(true));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Use the openDb helper to safely instantiate the database with Bun compatibility.

Suggested change
const db = new Database(dbPath, databaseOptions(true));
const db = openDb(dbPath, true);

Comment thread src/lib/db/omp.ts
export function saveOmpCredentials(providerId: string, apiKey: string, baseUrl: string) {
const dbPath = getOmpDbPath();
const db = new Database(dbPath);
const db = new Database(dbPath, databaseOptions());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Use the openDb helper to safely instantiate the database with Bun compatibility.

Suggested change
const db = new Database(dbPath, databaseOptions());
const db = openDb(dbPath);

Comment thread src/lib/db/omp.ts
export function deleteOmpCredentials(providerId: string) {
const dbPath = getOmpDbPath();
const db = new Database(dbPath);
const db = new Database(dbPath, databaseOptions());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Use the openDb helper to safely instantiate the database with Bun compatibility.

Suggested change
const db = new Database(dbPath, databaseOptions());
const db = openDb(dbPath);

Comment on lines +129 to +139
async backup(destination: string): Promise<void> {
if (filePath === ":memory:") return;
if (typeof db.serialize === "function") {
fs.writeFileSync(destination, Buffer.from(db.serialize()));
return;
}
try {
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
} catch {}
fs.copyFileSync(filePath, destination);
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using db.serialize() for physical file-backed databases is highly inefficient and poses a significant Out Of Memory (OOM) risk for large databases because it loads the entire database into memory as a Uint8Array. Since filePath is already verified to not be ":memory:", we should perform a standard checkpoint and use fs.copyFileSync directly.

    async backup(destination: string): Promise<void> {
      if (filePath === ":memory:") return;
      try {
        db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
      } catch {}
      fs.copyFileSync(filePath, destination);
    },

Comment thread bin/cli/sqlite.mjs
Comment on lines +118 to +127
if (typeof db.backup === "function") {
await db.backup(destPath);
} else if (typeof db.serialize === "function") {
fs.writeFileSync(destPath, Buffer.from(db.serialize()));
} else {
try {
db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
} catch {}
fs.copyFileSync(sourcePath, destPath);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using db.serialize() for physical file-backed databases is highly inefficient and poses a significant Out Of Memory (OOM) risk for large databases because it loads the entire database into memory as a Uint8Array. Since sourcePath is a physical file, we should perform a standard checkpoint and use fs.copyFileSync directly.

    if (typeof db.backup === "function") {
      await db.backup(destPath);
    } else {
      try {
        db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
      } catch {}
      fs.copyFileSync(sourcePath, destPath);
    }

Comment thread bin/cli/sqlite.mjs Outdated
Comment on lines +19 to +33
const normalizeParams = (params) => {
if (params.length !== 1 || params[0] === null || typeof params[0] !== "object" || Array.isArray(params[0])) {
return params;
}
const expanded = {};
for (const [key, value] of Object.entries(params[0])) {
if (/^[:@$]/.test(key)) expanded[key] = value;
else {
expanded[`@${key}`] = value;
expanded[`:${key}`] = value;
expanded[`$${key}`] = value;
}
}
return [expanded];
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In normalizeParams, there is no check for Uint8Array or Buffer. If a binary parameter (such as an encrypted credential or hash) is passed as a Buffer or Uint8Array, typeof params[0] === "object" will be true, and it is not an Array, so it will enter the loop and attempt to expand its indexed properties (e.g., @0, :0, $0), corrupting the binary data. We should explicitly check and skip normalization for Uint8Array and Buffer instances.

  const normalizeParams = (params) => {
    if (
      params.length !== 1 ||
      params[0] === null ||
      typeof params[0] !== "object" ||
      Array.isArray(params[0]) ||
      params[0] instanceof Uint8Array ||
      (typeof Buffer !== "undefined" && Buffer.isBuffer(params[0]))
    ) {
      return params;
    }
    const expanded = {};
    for (const [key, value] of Object.entries(params[0])) {
      if (/^[:@$]/.test(key)) expanded[key] = value;
      else {
        expanded['@' + key] = value;
        expanded[':' + key] = value;
        expanded['$' + key] = value;
      }
    }
    return [expanded];
  };

@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for this — the bun:sqlite adapter itself is clean (typechecks, lints, and the existing db/omp.test.ts + driverFactory.test.ts pass unmodified against your changes), and the sql.js WASM-resolution fix for global installs is a good catch independent of the Bun work.

Before this can merge there's one policy question and a few concrete fixes needed:

  1. Policy: this repo's CLAUDE.md currently states Bun is a build/dev-script runner only and explicitly says not to widen it into "the published runtime" — which is exactly what serve.mjs/processSupervisor.mjs/sqlite.mjs now do when process.versions.bun is set. That's a call for @diegosouzapw to make explicitly (update the doc, or we scope this down) before it ships as real behavior.
  2. Backup ordering (robustness): bunSqliteAdapter.ts::backup() and bin/cli/sqlite.mjs::backupSqliteFile() both try db.serialize() (loads the whole DB into memory) before falling back to checkpoint+file-copy for on-disk databases. Bun has a tracked OOM issue on db.serialize() even for tiny in-memory DBs (Out of memory error using (empty) in-memory sqlite db on db.serialize oven-sh/bun#6549) — for a real multi-GB storage.sqlite, checkpoint+copy should be tried first and serialize reserved for :memory: only.
  3. Test coverage: I ran node --import tsx/esm --test tests/unit/db-adapters/bunSqliteAdapter.test.ts and got 1 test / 0 pass / 1 skipped — since this repo's CI runs test:unit under Node only, the new adapter has zero CI-exercised coverage right now. Pulling the pure param-normalization/pragma helpers out into Node-testable functions (or wiring a Bun-driven CI job) would close that gap.
  4. Minor drift: bin/cli/sqlite.mjs's normalizeParams() doesn't exclude Uint8Array/Buffer before expanding a single object param into named placeholders, unlike the TS adapter's version which does. Not reachable today (no current caller passes a Buffer), but worth aligning so it doesn't bite the next BLOB caller.

One correction to the automated review above: bun:sqlite's Database.prepare() does exist (per Bun's own API reference) and returns a run/get/all Statement, so omp.ts's direct usage is fine as written — no crash there.

Happy to help iterate on 1-4 once there's a steer on the policy question.

@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks for the follow-up work here — the bug-fix commit (Bun SQLite backups + params hardening) already addressed the review feedback, so the code side of this PR was in good shape.

The one remaining gap was in CLAUDE.md's policy language, not in the implementation: the previous wording read as "Bun is also a supported runtime for the published CLI/server," which conflicts with this project's actual runtime policy and quietly dropped three existing guardrails (the enumerated allowlist of gate/generator scripts, the explicit "do not widen Bun to npm install/build/pack-artifact/published runtime/test runners" ban, and the byte-identical validation requirement for any new Bun-invoking script).

I pushed a small doc-only commit to this branch that keeps your code untouched and rewrites just those two CLAUDE.md bullets:

  • Node remains the only supported runtime for the published omniroute CLI, server, and test suites.
  • The bun:sqlite path you added is documented as a best-effort compatibility path (so bun install -g omniroute can start without better-sqlite3), not a supported runtime — with the existing guardrails restored and test:bun:db referenced as its regression suite.

None of your src/, bin/, or test files were touched — only CLAUDE.md. I re-ran typecheck, the file-size and docs-sync gates, test:bun:db, and the driverFactory/cliSqlite test files locally; all green.

With that, this looks ready for the merge queue. Thanks again for the contribution!

@diegosouzapw
diegosouzapw marked this pull request as ready for review July 21, 2026 17:02
@diegosouzapw
diegosouzapw self-requested a review as a code owner July 21, 2026 17:02
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@diegosouzapw

Copy link
Copy Markdown
Owner

Validated in local merge-train on tomni-proxmox-113 @ db6718332763af295ec8374913f1f5eb7641734f (FAST gates green: static + changed tests + vitest)

@diegosouzapw
diegosouzapw merged commit edbce2e into diegosouzapw:release/v3.8.49 Jul 21, 2026
3 checks passed
diegosouzapw added a commit that referenced this pull request Jul 22, 2026
* fix(dashboard): resolve Kimi banner casing collision + shrink frozen test file (release tip)

- Rename src/app/(dashboard)/dashboard/kimiSponsorBanner.ts to
  kimiSponsorBannerGate.ts so it no longer differs from
  KimiSponsorBanner.tsx only by the first letter's case (breaks next
  build on case-insensitive filesystems). Updates the sole importer
  (KimiSponsorBanner.tsx) and the two tests that reference it.
- Extract the 8 Kimi/Moonshot featured-ordering tests out of the
  frozen tests/unit/providers-page-utils.test.ts (grown 3 lines past
  its 1294 cap by #8039's rebrand-comment update) into a new sibling
  file tests/unit/providers-page-utils-kimi.test.ts. No assertions
  dropped; both files pass in full (24 + 8 = 32 tests).

* fix(sse): register PromptQlExecutor in the executor registry (release tip)

getExecutor("promptql") had no entry in open-sse/executors/index.ts, so it
silently fell through to DefaultExecutor's provider fallback, which issues a
raw fetch() and returns the bare upstream Response instead of the executor
wrapper shape {response, url, headers, transformedBody}. The real
PromptQlExecutor class (open-sse/executors/promptql.ts) already honors the
contract correctly — it was just never wired into the registry.

Fixes tests/unit/executor-web-cookie-sweep.test.ts "promptql executor
returns wrapper shape".

* fix(i18n): backfill 2220 missing pt-BR keys to restore en.json parity (release tip)

pt-BR.json fell behind after #7935 restored +2220 keys into en.json and
vi.json but left pt-BR.json unmodified. Translated all missing entries to
Brazilian Portuguese, preserving ICU/interpolation placeholders and existing
terminology, and merged them mirroring en.json's key order so the diff is
additions-only (the small comma-only deletions are pure JSON reformatting
from new sibling keys).

* fix(providers): repair 4 pre-existing catalog/registry reds on release tip

- providers-constants-split.test.ts: APIKEY_PROVIDERS grew 182->187 (PR #7887
  added 5 free-tier providers: ainative/aion/sealion/routeway/nara). Verified
  no dup/loss (6-family partition sums exactly to 187) and updated the stale
  expected count + comment trail to match.
- cline registry: added the missing minimax/minimax-m3 free OpenRouter entry
  (#3321) and fixed the neighbouring nemotron-3-ultra-550b-a55b entry, which
  carried a stray ":free" id suffix and an imprecise 1_000_000 contextLength
  instead of the 1_048_576 the test (and every sibling 1M-context entry in
  this catalog) expects.
- promptqlModels.ts / registry/promptql/index.ts: PROMPTQL_FALLBACK_MODELS's
  minimax-m3 entry was missing supportsVision, and the registry mapping
  dropped it entirely (only id/name were passed through) — it was the sole
  minimax-m3 entry across the whole registry not flagged multimodal, despite
  every other provider (minimax, minimax-cn, ollama-cloud, trae, bazaarlink,
  clinepass, codebuddy-cn, opencode-zen/go, synthetic, huggingchat, lmarena)
  agreeing MiniMax-M3 supports vision. Added the field to the PromptQlModel
  type and threaded it through.
- tests/snapshots/provider/translate-path.json: regenerated the golden via
  UPDATE_GOLDEN=1. Diffed old vs new — zero providers removed, 5 added
  (ainative/aion/nara/routeway/sealion, matching #7887), and the only
  changed entry (cline) reflects the already-merged #7914 ClinePass header
  protocol change (Cline/<version> User-Agent + X-Task-ID) that a prior
  narrow golden touch-up missed capturing.

* fix(docs): repair docs-sync/env-sync/repo-contract gates (release tip)

Six pre-existing reds on release/v3.8.49, all "repo drifted from its own
documented contract":

- check-docs-counts-sync: free-tier headline was stale (~1.4B/~2.0B) vs the
  live catalog (~1.53B steady / ~2.15B first month, 43 pools). Updated
  README.md and docs/reference/FREE_TIERS.md to the live numbers and added a
  v3.8.49 correction note explaining the pool-count delta (39->43, #7840).
  Also fixed a soft executors-count drift in ARCHITECTURE.md (84->86,
  268->271 providers) while touching that line.
- release-green-docs-drift-7253: docs/proxy-subscriptions.md referenced a
  fabricated migration filename (123_proxy_subscriptions.sql); the real file
  is 131_proxy_subscriptions.sql. Fixed all 3 occurrences.
- check-env-doc-sync + issue-7793-env-doc-sync-repro: OMNIROUTE_DATA_DIR
  (DATA_DIR fallback alias read by
  open-sse/executors/promptql/threadSticky.ts) was undocumented. Added to
  .env.example and docs/reference/ENVIRONMENT.md.
- check-db-rules: src/lib/db/proxySubscriptions.ts (#7299) is a db-internal
  split of proxies.ts (kept under the frozen file-size cap) whose one export
  is already re-exported via proxies.ts -> localDb.ts. Added it to
  INTENTIONALLY_INTERNAL with the same db-internal justification used for
  identical split modules (apiKeyColumnFallbacks, providerNodeSelect,
  webSessionDedup) rather than a redundant direct re-export from localDb.ts.
- mcp-server-hollow-dist-deps: the sanity test expected better-sqlite3 among
  the MCP bundle's static top-level external imports. That's been stale
  since the pre-#7878 migration to a cascading SqliteAdapter driver factory
  (createRequire()-based lazy require, not a static import); better-sqlite3
  already has its own native-asset copy guarantee in assembleStandalone.mjs,
  unrelated to this test's EXTRA_MODULE_ENTRIES concern. Updated the
  assertion to a still-genuinely-static external (zod) with a comment
  explaining the change.

No production runtime behavior changed — docs, .env.example, and a checker
allowlist/test-expectation only.

* fix(dashboard): repair stale UI component-shape test assertions (release tip)

Two pre-existing reds in the dashboard UI component-contract cluster were
caused by test assertions that had gone stale after intentional, correct
refactors — not by real defects in the components:

- quota-pool-wizard-multi.test.ts: the step-3 preview assertion required
  the literal single-line substring "connectionIds.map((cid)". Prettier
  (100-char width, project config) legitimately breaks the
  connectionIds.map(...).filter(...) chain across lines because of the
  multi-line callback body, so the literal never matches. PoolWizard.tsx
  still builds previewByProvider correctly by mapping over connectionIds;
  updated the assertion to a regex that tolerates the line break.

- v388-phase1-screen-fixes.test.ts: the shared Select placeholder-guard
  assertion required the literal "!children && placeholder". An earlier,
  intentional i18n commit changed the hardcoded "Select an option" default
  to a translated fallback (`placeholder ?? t("selectOption")`), which
  requires parens around the ?? expression for operator precedence. The
  guard behavior is unchanged (still gated on !children); updated the
  assertion to match the current, correct guard shape.

Both fixes are read-only test-file changes; no production behavior changed.

review-reviews-v3814-fixes.test.ts still has one pre-existing, unrelated
red (LEDGER-4: minimax-m3 registry entries missing supportsVision) that
requires editing the promptql provider registry/catalog — out of this
cluster's scope, left untouched and reported separately.

* fix(providers): reconcile cline catalog contradictions + deterministic golden (release tip)

The first tip-green pass introduced 3 regressions caught by CI on sibling guard tests:

- clinepass-provider + cline-catalog-models-3321 encoded OPPOSITE expectations of
  the same cline model list (minimax presence, nvidia :free suffix). Reference
  upstream (OpenRouter free lineup) confirms nvidia/nemotron-3-ultra-550b-a55b:free
  (with :free, 1M ctx) is correct, so restore that id and fix #3321's stale no-:free
  assertion; add minimax/minimax-m3 (the real #3321 gap) to clinepass-provider's list.
- check-db-rules-classification froze INTENTIONALLY_INTERNAL at 35; proxySubscriptions
  was the intentional 36th entry — add it + bump the count.
- provider-translate-path golden stored a LITERAL Cline/3.8.49: clineAuth resolves the
  version from APP_CONFIG.version (stable), but the golden sanitizer collapsed only
  process.env.npm_package_version (unset under `node`, set under `npm run`) — so the
  golden was shard-dependent. Resolve APP_VERSION from APP_CONFIG.version like clineAuth
  and regenerate; now Cline/<APP> normalizes identically in every shard.

* fix(services): type execFile signal/killed in classifyError + ratchet dashboard baseline (release tip)

Pre-existing base-red on the tip's Fast Quality Gates (dashboard-typecheck), missed
in the first inventory:

- src/lib/services/installers/utils.ts TS2339 — `err.signal` was read off a value typed
  as NodeJS.ErrnoException, which @types/node does not declare `signal`/`killed` on
  (those belong to execFile's ExecFileException). Widen classifyError's param to type
  both, and drop the now-redundant `(err as … { killed })` cast.
- Ratchet config/quality/dashboard-typecheck-baseline.json down: 5 baselined errors were
  fixed by already-merged PRs but never ratcheted (OAuthModal TS2769 4→3 / TS2345 4→3,
  CliproxyModelMappingEditor TS2339, CompressionPreviewAccordion TS4104, MonacoEditor
  TS2307). Baseline now 254, matching live — gate exits 0.
@Arul-

Arul- commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for raising the size concern. I rechecked the merged patch and the 460 added lines break down as follows:

  • 151 lines: the Bun SQLite adapter, which maps Bun's query/run/get/all API onto OmniRoute's existing SqliteAdapter contract, including parameter normalization, transactions, pragmas, backup/checkpoint, lifecycle, and result normalization.
  • 77 lines: the CLI SQLite bridge, which needs a separate runtime boundary from the TypeScript adapter.
  • 54 lines: driver selection, Bun process spawning, OMP credential DB access, sql.js WASM resolution, and error reporting.
  • 132 lines: focused Bun/CLI regression tests.
  • 37 lines: CI, package wiring, and policy documentation.

The implementation intentionally preserves the existing Node driver/fallback chain and keeps Bun compatibility isolated behind the existing adapter contract. The backup path was changed to checkpoint and copy on-disk files rather than serializing them into memory. The dedicated Bun test job is necessary because the normal Node test suite skips Bun-only behavior.

There is some duplicated normalization/backup glue between the CLI and TypeScript boundaries, but extracting it would introduce a cross-package runtime dependency and would not materially reduce the patch. The remaining lines are therefore mostly contract adaptation and executable coverage rather than incidental complexity. Bun remains documented as a best-effort compatibility path, not a new supported published runtime.

@diegosouzapw diegosouzapw mentioned this pull request Jul 23, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
* feat: support Bun bundled SQLite runtime

* fix: harden Bun SQLite backups and params

* docs: keep Node as the only supported runtime; document bun:sqlite as best-effort compatibility path

Co-authored-by: Arul Kumaran <arul@luracast.com>

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…ouzapw#8055)

* fix(dashboard): resolve Kimi banner casing collision + shrink frozen test file (release tip)

- Rename src/app/(dashboard)/dashboard/kimiSponsorBanner.ts to
  kimiSponsorBannerGate.ts so it no longer differs from
  KimiSponsorBanner.tsx only by the first letter's case (breaks next
  build on case-insensitive filesystems). Updates the sole importer
  (KimiSponsorBanner.tsx) and the two tests that reference it.
- Extract the 8 Kimi/Moonshot featured-ordering tests out of the
  frozen tests/unit/providers-page-utils.test.ts (grown 3 lines past
  its 1294 cap by diegosouzapw#8039's rebrand-comment update) into a new sibling
  file tests/unit/providers-page-utils-kimi.test.ts. No assertions
  dropped; both files pass in full (24 + 8 = 32 tests).

* fix(sse): register PromptQlExecutor in the executor registry (release tip)

getExecutor("promptql") had no entry in open-sse/executors/index.ts, so it
silently fell through to DefaultExecutor's provider fallback, which issues a
raw fetch() and returns the bare upstream Response instead of the executor
wrapper shape {response, url, headers, transformedBody}. The real
PromptQlExecutor class (open-sse/executors/promptql.ts) already honors the
contract correctly — it was just never wired into the registry.

Fixes tests/unit/executor-web-cookie-sweep.test.ts "promptql executor
returns wrapper shape".

* fix(i18n): backfill 2220 missing pt-BR keys to restore en.json parity (release tip)

pt-BR.json fell behind after diegosouzapw#7935 restored +2220 keys into en.json and
vi.json but left pt-BR.json unmodified. Translated all missing entries to
Brazilian Portuguese, preserving ICU/interpolation placeholders and existing
terminology, and merged them mirroring en.json's key order so the diff is
additions-only (the small comma-only deletions are pure JSON reformatting
from new sibling keys).

* fix(providers): repair 4 pre-existing catalog/registry reds on release tip

- providers-constants-split.test.ts: APIKEY_PROVIDERS grew 182->187 (PR diegosouzapw#7887
  added 5 free-tier providers: ainative/aion/sealion/routeway/nara). Verified
  no dup/loss (6-family partition sums exactly to 187) and updated the stale
  expected count + comment trail to match.
- cline registry: added the missing minimax/minimax-m3 free OpenRouter entry
  (diegosouzapw#3321) and fixed the neighbouring nemotron-3-ultra-550b-a55b entry, which
  carried a stray ":free" id suffix and an imprecise 1_000_000 contextLength
  instead of the 1_048_576 the test (and every sibling 1M-context entry in
  this catalog) expects.
- promptqlModels.ts / registry/promptql/index.ts: PROMPTQL_FALLBACK_MODELS's
  minimax-m3 entry was missing supportsVision, and the registry mapping
  dropped it entirely (only id/name were passed through) — it was the sole
  minimax-m3 entry across the whole registry not flagged multimodal, despite
  every other provider (minimax, minimax-cn, ollama-cloud, trae, bazaarlink,
  clinepass, codebuddy-cn, opencode-zen/go, synthetic, huggingchat, lmarena)
  agreeing MiniMax-M3 supports vision. Added the field to the PromptQlModel
  type and threaded it through.
- tests/snapshots/provider/translate-path.json: regenerated the golden via
  UPDATE_GOLDEN=1. Diffed old vs new — zero providers removed, 5 added
  (ainative/aion/nara/routeway/sealion, matching diegosouzapw#7887), and the only
  changed entry (cline) reflects the already-merged diegosouzapw#7914 ClinePass header
  protocol change (Cline/<version> User-Agent + X-Task-ID) that a prior
  narrow golden touch-up missed capturing.

* fix(docs): repair docs-sync/env-sync/repo-contract gates (release tip)

Six pre-existing reds on release/v3.8.49, all "repo drifted from its own
documented contract":

- check-docs-counts-sync: free-tier headline was stale (~1.4B/~2.0B) vs the
  live catalog (~1.53B steady / ~2.15B first month, 43 pools). Updated
  README.md and docs/reference/FREE_TIERS.md to the live numbers and added a
  v3.8.49 correction note explaining the pool-count delta (39->43, diegosouzapw#7840).
  Also fixed a soft executors-count drift in ARCHITECTURE.md (84->86,
  268->271 providers) while touching that line.
- release-green-docs-drift-7253: docs/proxy-subscriptions.md referenced a
  fabricated migration filename (123_proxy_subscriptions.sql); the real file
  is 131_proxy_subscriptions.sql. Fixed all 3 occurrences.
- check-env-doc-sync + issue-7793-env-doc-sync-repro: OMNIROUTE_DATA_DIR
  (DATA_DIR fallback alias read by
  open-sse/executors/promptql/threadSticky.ts) was undocumented. Added to
  .env.example and docs/reference/ENVIRONMENT.md.
- check-db-rules: src/lib/db/proxySubscriptions.ts (diegosouzapw#7299) is a db-internal
  split of proxies.ts (kept under the frozen file-size cap) whose one export
  is already re-exported via proxies.ts -> localDb.ts. Added it to
  INTENTIONALLY_INTERNAL with the same db-internal justification used for
  identical split modules (apiKeyColumnFallbacks, providerNodeSelect,
  webSessionDedup) rather than a redundant direct re-export from localDb.ts.
- mcp-server-hollow-dist-deps: the sanity test expected better-sqlite3 among
  the MCP bundle's static top-level external imports. That's been stale
  since the pre-diegosouzapw#7878 migration to a cascading SqliteAdapter driver factory
  (createRequire()-based lazy require, not a static import); better-sqlite3
  already has its own native-asset copy guarantee in assembleStandalone.mjs,
  unrelated to this test's EXTRA_MODULE_ENTRIES concern. Updated the
  assertion to a still-genuinely-static external (zod) with a comment
  explaining the change.

No production runtime behavior changed — docs, .env.example, and a checker
allowlist/test-expectation only.

* fix(dashboard): repair stale UI component-shape test assertions (release tip)

Two pre-existing reds in the dashboard UI component-contract cluster were
caused by test assertions that had gone stale after intentional, correct
refactors — not by real defects in the components:

- quota-pool-wizard-multi.test.ts: the step-3 preview assertion required
  the literal single-line substring "connectionIds.map((cid)". Prettier
  (100-char width, project config) legitimately breaks the
  connectionIds.map(...).filter(...) chain across lines because of the
  multi-line callback body, so the literal never matches. PoolWizard.tsx
  still builds previewByProvider correctly by mapping over connectionIds;
  updated the assertion to a regex that tolerates the line break.

- v388-phase1-screen-fixes.test.ts: the shared Select placeholder-guard
  assertion required the literal "!children && placeholder". An earlier,
  intentional i18n commit changed the hardcoded "Select an option" default
  to a translated fallback (`placeholder ?? t("selectOption")`), which
  requires parens around the ?? expression for operator precedence. The
  guard behavior is unchanged (still gated on !children); updated the
  assertion to match the current, correct guard shape.

Both fixes are read-only test-file changes; no production behavior changed.

review-reviews-v3814-fixes.test.ts still has one pre-existing, unrelated
red (LEDGER-4: minimax-m3 registry entries missing supportsVision) that
requires editing the promptql provider registry/catalog — out of this
cluster's scope, left untouched and reported separately.

* fix(providers): reconcile cline catalog contradictions + deterministic golden (release tip)

The first tip-green pass introduced 3 regressions caught by CI on sibling guard tests:

- clinepass-provider + cline-catalog-models-3321 encoded OPPOSITE expectations of
  the same cline model list (minimax presence, nvidia :free suffix). Reference
  upstream (OpenRouter free lineup) confirms nvidia/nemotron-3-ultra-550b-a55b:free
  (with :free, 1M ctx) is correct, so restore that id and fix diegosouzapw#3321's stale no-:free
  assertion; add minimax/minimax-m3 (the real diegosouzapw#3321 gap) to clinepass-provider's list.
- check-db-rules-classification froze INTENTIONALLY_INTERNAL at 35; proxySubscriptions
  was the intentional 36th entry — add it + bump the count.
- provider-translate-path golden stored a LITERAL Cline/3.8.49: clineAuth resolves the
  version from APP_CONFIG.version (stable), but the golden sanitizer collapsed only
  process.env.npm_package_version (unset under `node`, set under `npm run`) — so the
  golden was shard-dependent. Resolve APP_VERSION from APP_CONFIG.version like clineAuth
  and regenerate; now Cline/<APP> normalizes identically in every shard.

* fix(services): type execFile signal/killed in classifyError + ratchet dashboard baseline (release tip)

Pre-existing base-red on the tip's Fast Quality Gates (dashboard-typecheck), missed
in the first inventory:

- src/lib/services/installers/utils.ts TS2339 — `err.signal` was read off a value typed
  as NodeJS.ErrnoException, which @types/node does not declare `signal`/`killed` on
  (those belong to execFile's ExecFileException). Widen classifyError's param to type
  both, and drop the now-redundant `(err as … { killed })` cast.
- Ratchet config/quality/dashboard-typecheck-baseline.json down: 5 baselined errors were
  fixed by already-merged PRs but never ratcheted (OAuthModal TS2769 4→3 / TS2345 4→3,
  CliproxyModelMappingEditor TS2339, CompressionPreviewAccordion TS4104, MonacoEditor
  TS2307). Baseline now 254, matching live — gate exits 0.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
* feat: support Bun bundled SQLite runtime

* fix: harden Bun SQLite backups and params

* docs: keep Node as the only supported runtime; document bun:sqlite as best-effort compatibility path

Co-authored-by: Arul Kumaran <arul@luracast.com>

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ouzapw#8055)

* fix(dashboard): resolve Kimi banner casing collision + shrink frozen test file (release tip)

- Rename src/app/(dashboard)/dashboard/kimiSponsorBanner.ts to
  kimiSponsorBannerGate.ts so it no longer differs from
  KimiSponsorBanner.tsx only by the first letter's case (breaks next
  build on case-insensitive filesystems). Updates the sole importer
  (KimiSponsorBanner.tsx) and the two tests that reference it.
- Extract the 8 Kimi/Moonshot featured-ordering tests out of the
  frozen tests/unit/providers-page-utils.test.ts (grown 3 lines past
  its 1294 cap by diegosouzapw#8039's rebrand-comment update) into a new sibling
  file tests/unit/providers-page-utils-kimi.test.ts. No assertions
  dropped; both files pass in full (24 + 8 = 32 tests).

* fix(sse): register PromptQlExecutor in the executor registry (release tip)

getExecutor("promptql") had no entry in open-sse/executors/index.ts, so it
silently fell through to DefaultExecutor's provider fallback, which issues a
raw fetch() and returns the bare upstream Response instead of the executor
wrapper shape {response, url, headers, transformedBody}. The real
PromptQlExecutor class (open-sse/executors/promptql.ts) already honors the
contract correctly — it was just never wired into the registry.

Fixes tests/unit/executor-web-cookie-sweep.test.ts "promptql executor
returns wrapper shape".

* fix(i18n): backfill 2220 missing pt-BR keys to restore en.json parity (release tip)

pt-BR.json fell behind after diegosouzapw#7935 restored +2220 keys into en.json and
vi.json but left pt-BR.json unmodified. Translated all missing entries to
Brazilian Portuguese, preserving ICU/interpolation placeholders and existing
terminology, and merged them mirroring en.json's key order so the diff is
additions-only (the small comma-only deletions are pure JSON reformatting
from new sibling keys).

* fix(providers): repair 4 pre-existing catalog/registry reds on release tip

- providers-constants-split.test.ts: APIKEY_PROVIDERS grew 182->187 (PR diegosouzapw#7887
  added 5 free-tier providers: ainative/aion/sealion/routeway/nara). Verified
  no dup/loss (6-family partition sums exactly to 187) and updated the stale
  expected count + comment trail to match.
- cline registry: added the missing minimax/minimax-m3 free OpenRouter entry
  (diegosouzapw#3321) and fixed the neighbouring nemotron-3-ultra-550b-a55b entry, which
  carried a stray ":free" id suffix and an imprecise 1_000_000 contextLength
  instead of the 1_048_576 the test (and every sibling 1M-context entry in
  this catalog) expects.
- promptqlModels.ts / registry/promptql/index.ts: PROMPTQL_FALLBACK_MODELS's
  minimax-m3 entry was missing supportsVision, and the registry mapping
  dropped it entirely (only id/name were passed through) — it was the sole
  minimax-m3 entry across the whole registry not flagged multimodal, despite
  every other provider (minimax, minimax-cn, ollama-cloud, trae, bazaarlink,
  clinepass, codebuddy-cn, opencode-zen/go, synthetic, huggingchat, lmarena)
  agreeing MiniMax-M3 supports vision. Added the field to the PromptQlModel
  type and threaded it through.
- tests/snapshots/provider/translate-path.json: regenerated the golden via
  UPDATE_GOLDEN=1. Diffed old vs new — zero providers removed, 5 added
  (ainative/aion/nara/routeway/sealion, matching diegosouzapw#7887), and the only
  changed entry (cline) reflects the already-merged diegosouzapw#7914 ClinePass header
  protocol change (Cline/<version> User-Agent + X-Task-ID) that a prior
  narrow golden touch-up missed capturing.

* fix(docs): repair docs-sync/env-sync/repo-contract gates (release tip)

Six pre-existing reds on release/v3.8.49, all "repo drifted from its own
documented contract":

- check-docs-counts-sync: free-tier headline was stale (~1.4B/~2.0B) vs the
  live catalog (~1.53B steady / ~2.15B first month, 43 pools). Updated
  README.md and docs/reference/FREE_TIERS.md to the live numbers and added a
  v3.8.49 correction note explaining the pool-count delta (39->43, diegosouzapw#7840).
  Also fixed a soft executors-count drift in ARCHITECTURE.md (84->86,
  268->271 providers) while touching that line.
- release-green-docs-drift-7253: docs/proxy-subscriptions.md referenced a
  fabricated migration filename (123_proxy_subscriptions.sql); the real file
  is 131_proxy_subscriptions.sql. Fixed all 3 occurrences.
- check-env-doc-sync + issue-7793-env-doc-sync-repro: OMNIROUTE_DATA_DIR
  (DATA_DIR fallback alias read by
  open-sse/executors/promptql/threadSticky.ts) was undocumented. Added to
  .env.example and docs/reference/ENVIRONMENT.md.
- check-db-rules: src/lib/db/proxySubscriptions.ts (diegosouzapw#7299) is a db-internal
  split of proxies.ts (kept under the frozen file-size cap) whose one export
  is already re-exported via proxies.ts -> localDb.ts. Added it to
  INTENTIONALLY_INTERNAL with the same db-internal justification used for
  identical split modules (apiKeyColumnFallbacks, providerNodeSelect,
  webSessionDedup) rather than a redundant direct re-export from localDb.ts.
- mcp-server-hollow-dist-deps: the sanity test expected better-sqlite3 among
  the MCP bundle's static top-level external imports. That's been stale
  since the pre-diegosouzapw#7878 migration to a cascading SqliteAdapter driver factory
  (createRequire()-based lazy require, not a static import); better-sqlite3
  already has its own native-asset copy guarantee in assembleStandalone.mjs,
  unrelated to this test's EXTRA_MODULE_ENTRIES concern. Updated the
  assertion to a still-genuinely-static external (zod) with a comment
  explaining the change.

No production runtime behavior changed — docs, .env.example, and a checker
allowlist/test-expectation only.

* fix(dashboard): repair stale UI component-shape test assertions (release tip)

Two pre-existing reds in the dashboard UI component-contract cluster were
caused by test assertions that had gone stale after intentional, correct
refactors — not by real defects in the components:

- quota-pool-wizard-multi.test.ts: the step-3 preview assertion required
  the literal single-line substring "connectionIds.map((cid)". Prettier
  (100-char width, project config) legitimately breaks the
  connectionIds.map(...).filter(...) chain across lines because of the
  multi-line callback body, so the literal never matches. PoolWizard.tsx
  still builds previewByProvider correctly by mapping over connectionIds;
  updated the assertion to a regex that tolerates the line break.

- v388-phase1-screen-fixes.test.ts: the shared Select placeholder-guard
  assertion required the literal "!children && placeholder". An earlier,
  intentional i18n commit changed the hardcoded "Select an option" default
  to a translated fallback (`placeholder ?? t("selectOption")`), which
  requires parens around the ?? expression for operator precedence. The
  guard behavior is unchanged (still gated on !children); updated the
  assertion to match the current, correct guard shape.

Both fixes are read-only test-file changes; no production behavior changed.

review-reviews-v3814-fixes.test.ts still has one pre-existing, unrelated
red (LEDGER-4: minimax-m3 registry entries missing supportsVision) that
requires editing the promptql provider registry/catalog — out of this
cluster's scope, left untouched and reported separately.

* fix(providers): reconcile cline catalog contradictions + deterministic golden (release tip)

The first tip-green pass introduced 3 regressions caught by CI on sibling guard tests:

- clinepass-provider + cline-catalog-models-3321 encoded OPPOSITE expectations of
  the same cline model list (minimax presence, nvidia :free suffix). Reference
  upstream (OpenRouter free lineup) confirms nvidia/nemotron-3-ultra-550b-a55b:free
  (with :free, 1M ctx) is correct, so restore that id and fix diegosouzapw#3321's stale no-:free
  assertion; add minimax/minimax-m3 (the real diegosouzapw#3321 gap) to clinepass-provider's list.
- check-db-rules-classification froze INTENTIONALLY_INTERNAL at 35; proxySubscriptions
  was the intentional 36th entry — add it + bump the count.
- provider-translate-path golden stored a LITERAL Cline/3.8.49: clineAuth resolves the
  version from APP_CONFIG.version (stable), but the golden sanitizer collapsed only
  process.env.npm_package_version (unset under `node`, set under `npm run`) — so the
  golden was shard-dependent. Resolve APP_VERSION from APP_CONFIG.version like clineAuth
  and regenerate; now Cline/<APP> normalizes identically in every shard.

* fix(services): type execFile signal/killed in classifyError + ratchet dashboard baseline (release tip)

Pre-existing base-red on the tip's Fast Quality Gates (dashboard-typecheck), missed
in the first inventory:

- src/lib/services/installers/utils.ts TS2339 — `err.signal` was read off a value typed
  as NodeJS.ErrnoException, which @types/node does not declare `signal`/`killed` on
  (those belong to execFile's ExecFileException). Widen classifyError's param to type
  both, and drop the now-redundant `(err as … { killed })` cast.
- Ratchet config/quality/dashboard-typecheck-baseline.json down: 5 baselined errors were
  fixed by already-merged PRs but never ratcheted (OAuthModal TS2769 4→3 / TS2345 4→3,
  CliproxyModelMappingEditor TS2339, CompressionPreviewAccordion TS4104, MonacoEditor
  TS2307). Baseline now 254, matching live — gate exits 0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants