* fix(build): exec native tool binaries directly in runBuildTool
#8858 routed every resolved local bin through process.execPath to avoid
Windows .cmd shims — but esbuild >=0.25 ships bin/esbuild as the NATIVE
platform executable (ELF on Linux), so Node parsed machine code as JS and
build:cli died with 'SyntaxError: Invalid or unexpected token', turning
dast-smoke red for every PR.
runBuildTool now sniffs the entry's magic bytes (ELF / Mach-O / PE) and
execs native binaries directly; JS entries keep going through this Node
binary (the .cmd-shim avoidance #8858 wanted).
Validation (RED->GREEN on this box):
- RED: node node_modules/esbuild/bin/esbuild --version -> SyntaxError (ELF)
- GREEN: the exact failing CI step reproduced via the new logic bundles
open-sse/mcp-server/server.ts successfully (4.2MB output, 1.3s).
* fix(docs): add MDX frontmatter to the 20 remaining docs without it
Same failure class as AGENTROUTER_WAF (#9503) and DOCKER_RELEASE_CHANNELS
(this run's dast-smoke red): any doc without frontmatter breaks the
fumadocs MDX loader during next build, killing build:cli/dast-smoke for
every PR. Swept ALL of docs/ (i18n mirrors excluded) in one pass so this
class cannot recur one file at a time.
* docs(env): document OMNIROUTE_INTERNAL_SERVICE_TOKEN(+_FILE), OPENROUTER_PROVIDER_STATS_* and embedded-Redis binding vars
Pre-existing env/docs contract drift from recently merged features made
check:env-doc-sync red for any docs-touching PR. Values and defaults read
from the defining modules (internalServiceAuth.ts, openrouterProviderStats.ts).
* fix(build): resolve bundled npm-cli.js in the standard Unix layout + safe npm fallback off-Windows
The opencode-plugin step hard-failed on GitHub runners because
resolveBundledNpmEntry only looked next to the node binary (Windows zip
layout); hostedtoolcache Node keeps npm at <prefix>/lib/node_modules/npm.
Added that candidate, and when neither exists on non-Windows the step now
falls back to plain 'npm' — the .cmd-shim hazard #8858 avoids is
Windows-only.
* test(mutation): register xai-agent-tools-passthrough.test.ts in stryker tap.testFiles
The test landed on release/v3.8.50 covering
open-sse/handlers/chatCore/passthroughHelpers.ts without the stryker
registration, so Fast Quality Gates' drift detection reds any PR that
carries it. Mechanical registration so its mutant kills count.
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* fix(mcp): give the audit tests a loader seam createRequire cannot hide from
Since #8959 the audit DB loads better-sqlite3 via createRequire() (so
Electron/global-install resolution works) — which vi.doMock cannot
intercept: it only patches Vitest's ESM module graph. The audit.test.ts
better-sqlite3 mock therefore never engaged; the tests opened a REAL
empty sqlite file in the temp DATA_DIR ('no such table: mcp_tool_audit'
on stderr) and every mock assertion counted zero calls. The 3 failures
are deterministic (reproduced 3/3 locally), redding Vitest (fast-path)
for the entire PR queue — long misdiagnosed as a flake (#9095 merge
notes call it 'pre-existing audit.test.ts flake').
- Shutdown tests inject the mock through the audit connection cache
(globalThis.__omnirouteMcpAuditDb) — the module's own seam.
- The node:sqlite fallback test drives __setBetterSqliteLoaderForTests,
a test-only loader override; the production createRequire path is
untouched (node:sqlite itself is import()'d, so its doMock still
works).
3/3 red -> 3/3 green; full open-sse/mcp-server vitest suite 88/88.
* chore: align changelog slug with the PR number (9559)
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* fix(quality): reconcile inherited file-size drift on the release tip
13 files sit above their frozen LOC on the clean tip 8180b49ce1
(measured by the gate itself). The PR-mode base-relative check (#8522)
correctly lets innocent PRs pass, but per-PR rebaselines were lost
across successive conflict resolutions of this hot file during the
08-05/06 merge batch — so the absolute mode (nightly, local runs) is
permanently red and stops distinguishing real growth from inherited
drift.
Frozen values updated to the measured tip, each annotated with the
merged PR that grew the file (#9024#9324#9329#9193#9332#9228#9236#9314#9260#8934#9196#9163); executors default.ts and kiro.ts
(above the 1000 cap with no frozen entry) join the frozen set.
* fix(quality): prune orphaned ESLint suppressions and clear the 5 unsuppressed errors
The 'No new ESLint warnings' job reds the whole queue with exit 2:
'There are suppressions left that do not occur anymore' — the 08-05
merge batch removed code whose violations were frozen in
eslint-suppressions.json, leaving orphaned entries (673->670 files,
4338->4333 violations after eslint --prune-suppressions).
The full-tree run also surfaced 5 real unsuppressed errors merged with
the batch, fixed here instead of suppressed (new violations must be
fixed, per policy): 4x no-explicit-any in
tests/unit/catalog-order-contract.test.ts ((conn as any).id -> typed
cast) and 1x react/no-unescaped-entities in the agent-bridge
SetupWizard (#9095).
Also restores the _comment policy header the successive hot-file
conflict resolutions had dropped (TS7 debt freeze provenance + prune
policy).
* fix(quality): absorb the two file-size growths merged while this PR was in CI
The base kept moving during the reconcile cycle: #9184 grew
src/sse/handlers/chat.ts 1857->1877 and #9005 grew
open-sse/executors/default.ts 1027->1042. Re-measured on the merged
tree; gate back to 0 violations.
* fix(tests): move the orphaned RTL ratchet test to a collected path as node:test
#8828 added tests/unit/scripts/check-rtl-ratchet.test.ts — a path no
runner collects (the node:test globs enumerate an explicit subdir list
without scripts/, and vitest.config.ts never included it), so the file
NEVER ran and the test-discovery orphan gate reds the queue. Moved to
tests/unit/ (collected by node:test) and converted from vitest
describe/it/expect to node:test+assert to match the runner and the
sibling check-*.test.ts files. 5/5 green under the real runner.
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
* fix(build): resolve npm-cli.js on POSIX layouts in the shim-free prepublish resolver
The #8858 resolver only tried <dir(node)>/node_modules/npm/bin — the
Windows layout. On POSIX (GitHub hosted runners, nvm, system installs)
npm lives at <prefix>/lib/node_modules/npm while node is <prefix>/bin/
node, so resolveBundledNpmEntry returned null and npm run build:cli
died installing @omniroute/opencode-plugin deps on every fresh checkout
('npm-cli.js not found next to the running Node binary') — redding Fast
Production Build and dast-smoke for the whole PR queue.
Extract the resolver to scripts/build/resolveNpmEntry.ts with injectable
seams and try, in order: npm_execpath (exported by npm run itself), the
Windows beside-the-binary layout, the POSIX <prefix>/lib layout.
TDD: tests/unit/build/resolve-npm-entry.test.ts — the POSIX-layout and
npm_execpath cases plus a live regression guard fail against the old
single-candidate logic (2/5) and pass with the fix (5/5).
* docs(env): register the 7 env vars orphaned by the 08-05 merge batch
The Docs Gates env/docs contract went red on the release tip: #9260
added OMNIROUTE_INTERNAL_SERVICE_TOKEN(_FILE) and #9324 added
OPENROUTER_PROVIDER_STATS_ENABLED/_TTL_MS without .env.example entries,
and the #9286 Redis sidecar vars (REDIS_BIND_HOST, REDIS_PORT,
OMNIROUTE_REDIS_BIND_HOST) never reached ENVIRONMENT.md. Inherited
base-red on every open PR. Defaults and descriptions taken from the
consuming source files.
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>