Skip to content

deps: bump the development group across 1 directory with 9 updates - #3916

Closed
dependabot[bot] wants to merge 1 commit into
release/v3.8.27from
dependabot/npm_and_yarn/development-2b6164e598
Closed

dependabot[bot] wants to merge 1 commit into
release/v3.8.27from
dependabot/npm_and_yarn/development-2b6164e598

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Bumps the development group with 8 updates in the / directory:

Package From To
@playwright/test 1.60.0 1.61.0
@tailwindcss/postcss 4.3.0 4.3.1
@types/node 25.9.2 25.9.3
eslint-config-next 16.2.7 16.2.9
jscpd 4.2.5 5.0.9
prettier 3.8.3 3.8.4
typescript-eslint 8.61.0 8.61.1
vitest 4.1.8 4.1.9

Updates @playwright/test from 1.60.0 to 1.61.0

Release notes

Sourced from @​playwright/test's releases.

v1.61.0

🔑 WebAuthn passkeys

New Credentials virtual authenticator, available via browserContext.credentials, lets tests register passkeys and answer navigator.credentials.create() / navigator.credentials.get() ceremonies in the page — no real hardware key required, works in all browsers:

const context = await browser.newContext();
// Seed a passkey your backend provisioned for a test user.
await context.credentials.create('example.com', {
id: credentialId,
userHandle,
privateKey,
publicKey,
});
await context.credentials.install();
const page = await context.newPage();
await page.goto('https://example.com/login');
// The page's navigator.credentials.get() is answered with the seeded passkey.

You can also let the app register a passkey once in a setup test, read it back with credentials.get(), and seed it into later tests — see Credentials for details.

🗃️ Web Storage

New WebStorage API, available via page.localStorage and page.sessionStorage, reads and writes the page's storage for the current origin:

await page.localStorage.setItem('token', 'abc');
const token = await page.localStorage.getItem('token');
const items = await page.sessionStorage.items();

New APIs

Network

Browser and Screencast

  • New option artifactsDir in browserType.connectOverCDP() controls where artifacts such as traces and downloads are stored when attached to an existing browser.
  • New option cursor in screencast.showActions() controls the cursor decoration rendered for pointer actions.
  • The onFrame callback in screencast.start() now receives a timestamp of when the frame was presented by the browser.

Test runner

  • The testOptions.video option now supports the same set of modes as trace: new 'on-all-retries', 'retain-on-first-failure' and 'retain-on-failure-and-retries' values. See the video modes table for which runs are recorded and kept in each mode.
  • Supported expect.soft.poll(...).
  • New fullConfig.argv — a snapshot of process.argv from the runner process, handy for reading custom arguments passed after the -- separator.
  • New fullConfig.failOnFlakyTests mirrors the config option, so reporters can explain why a flaky run failed.
  • testInfo.errors now lists each sub-error of an AggregateError as a separate entry.

... (truncated)

Commits
  • 1cc5a90 cherry-pick(#41295): chore: PLAYWRIGHT_TRACING_NO_WEBSOCKET_FRAMES and PLAYWR...
  • a6772bd cherry-pick(#41280): Revert "fix(trace-viewer): add keyboard navigation to `N...
  • 8133dcf cherry-pick(#41283): docs: add Ubuntu 26.04 and Node.js 26.x to system requir...
  • 812432e chore: mark v1.61.0 (#41277)
  • ac05145 fix(fetch): report serverAddr and securityDetails for reused sockets (#41267)
  • 056efc9 fix(trace-viewer): add keyboard navigation to NetworkFilters component (#41...
  • 41f7b9a chore: fixes uncovered by the .NET 1.61 roll (#41266)
  • ba50778 fix(mcp): assign caps as array for legacy --vision flag (#41253)
  • b8ee5ae docs: release notes for v1.61 (#41261)
  • 49c1f69 fix(trace viewer): load trace from a local file (#41263)
  • Additional commits viewable in compare view

Updates @tailwindcss/postcss from 4.3.0 to 4.3.1

Release notes

Sourced from @​tailwindcss/postcss's releases.

v4.3.1

Added

  • Add --silent option to suppress output in @tailwindcss/cli (#20100)

Fixed

  • Remove deprecation warnings by using Module#registerHooks instead of Module#register on Node 26+ (#20028)
  • Canonicalization: don't crash when plugin utilities throw for unsupported values (#20052)
  • Allow @apply to be used with CSS mixins (#19427)
  • Ensure not-* correctly negates @container queries, including style(…) queries (#20059)
  • Ensure drop-shadow-* color utilities work with custom shadow values containing calc(…) (#20080)
  • Fix 'Sourcemap is likely to be incorrect' warnings when using @tailwindcss/vite (#20103)
  • Ensure @tailwindcss/webpack can be installed in Rspack projects without requiring webpack as a peer dependency (#20027)
  • Canonicalization: don't suggest invalid calc(…) expressions (e.g. px-[calc(1rem+0px)] → px-[calc(1rem+0)]) (#20127)
  • Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. left-[99999px] → left-[99999px], not left-24999.75) (#20130)
  • Ensure @tailwindcss/cli in --watch mode recovers when a tracked dependency is deleted and restored (#20137)
  • Ensure standalone @tailwindcss/cli binaries are ignored when scanning for class candidates (#20139)
  • Ensure class candidates are extracted from Twig addClass(…) and removeClass(…) calls (#20198)
  • Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes (#19588)
  • Allow @variant to be used inside addBase (#19480)
  • Ensure @source globs with symlinks are preserved (#20203)
  • Ensure later @source rules can re-include files excluded by earlier @source not rules (#20203)
  • Upgrade: don't migrate empty class rules to invalid @utility rules (#20205)
  • Ensure transitions between inset-shadow-none and other inset shadows work correctly (#20208)
  • Ensure explicitly referenced @source directories are scanned even when ignored by git (#20214)
  • Ensure @source globs ending in **/* preserve dynamic path segments to avoid scanning too many files (#20217)
  • Canonicalization: don't fold calc(…) divisions when the result would require high precision (e.g. w-[calc(100%/3.5)] → w-[calc(100%/3.5)], not w-[28.571428571428573%]) (#20221)
  • Serve ESM type declarations to ESM importers of @tailwindcss/postcss (#20228)

Changed

  • Generate 0 instead of calc(var(--spacing) * 0) for spacing utilities like m-0 and left-0 (#20196)
  • Generate var(--spacing) instead of calc(var(--spacing) * 1) for spacing utilities like m-1 and left-1 (#20196)
Changelog

Sourced from @​tailwindcss/postcss's changelog.

[4.3.1] - 2026-06-12

Added

  • Add --silent option to suppress output in @tailwindcss/cli (#20100)

Fixed

  • Remove deprecation warnings by using Module#registerHooks instead of Module#register on Node 26+ (#20028)
  • Canonicalization: don't crash when plugin utilities throw for unsupported values (#20052)
  • Allow @apply to be used with CSS mixins (#19427)
  • Ensure not-* correctly negates @container queries, including style(…) queries (#20059)
  • Ensure drop-shadow-* color utilities work with custom shadow values containing calc(…) (#20080)
  • Fix 'Sourcemap is likely to be incorrect' warnings when using @tailwindcss/vite (#20103)
  • Ensure @tailwindcss/webpack can be installed in Rspack projects without requiring webpack as a peer dependency (#20027)
  • Canonicalization: don't suggest invalid calc(…) expressions (e.g. px-[calc(1rem+0px)] → px-[calc(1rem+0)]) (#20127)
  • Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. left-[99999px] → left-[99999px], not left-24999.75) (#20130)
  • Ensure @tailwindcss/cli in --watch mode recovers when a tracked dependency is deleted and restored (#20137)
  • Ensure standalone @tailwindcss/cli binaries are ignored when scanning for class candidates (#20139)
  • Ensure class candidates are extracted from Twig addClass(…) and removeClass(…) calls (#20198)
  • Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes (#19588)
  • Allow @variant to be used inside addBase (#19480)
  • Ensure @source globs with symlinks are preserved (#20203)
  • Ensure later @source rules can re-include files excluded by earlier @source not rules (#20203)
  • Upgrade: don't migrate empty class rules to invalid @utility rules (#20205)
  • Ensure transitions between inset-shadow-none and other inset shadows work correctly (#20208)
  • Ensure explicitly referenced @source directories are scanned even when ignored by git (#20214)
  • Ensure @source globs ending in **/* preserve dynamic path segments to avoid scanning too many files (#20217)
  • Canonicalization: don't fold calc(…) divisions when the result would require high precision (e.g. w-[calc(100%/3.5)] → w-[calc(100%/3.5)], not w-[28.571428571428573%]) (#20221)
  • Serve ESM type declarations to ESM importers of @tailwindcss/postcss (#20228)

Changed

  • Generate 0 instead of calc(var(--spacing) * 0) for spacing utilities like m-0 and left-0 (#20196)
  • Generate var(--spacing) instead of calc(var(--spacing) * 1) for spacing utilities like m-1 and left-1 (#20196)
Commits

Updates @types/node from 25.9.2 to 25.9.3

Commits

Updates eslint-config-next from 16.2.7 to 16.2.9

Release notes

Sourced from eslint-config-next's releases.

v16.2.9

Empty release to ensure next@latest points at a stable release. Next.js only allows publishing with Trusted Publishing enabled. In order to fix NPM dist-tags, we have to release a new version. Updating dist-tags is not possible with Trusted Publishing.

v16.2.8

Release with no changes in an attempt to fix next@latest pointing at a prerelease version.

Commits

Updates jscpd from 4.2.5 to 5.0.9

Release notes

Sourced from jscpd's releases.

v5.0.9

New Features

  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5

Bug Fixes

  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #816

Release v5.0.8

Bug Fixes

  • Prevent mmap exhaustion crashes when scanning repositories with more files than (default 131 072 on Linux). The walker previously held a live per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #813
  • Fix not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like gain a prefix to match at any depth. Fixes #811

Release v5.0.7

Bug Fixes

  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default to — files exceeding the limit are skipped at walk time, consistent with jscpd v4's behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • now correctly takes effect on every call (previously silently no-op'd after the first invocation)

Release v5.0.6

New Features

  • v4 config backward compatibility — fields , , , and are now read and applied, matching jscpd v4 behavior
  • and are now distinct: matches file-level globs, matches code-level regex patterns (previously conflated)
  • path config support — reads scan directories from the field, resolving relative paths against the config file's directory
  • npm wrapper package — publishes the same Rust binary under the name on npm with v5.x versioning
  • now matches v4 behavior: accepts optional integer value ( exits 1, exits 2); and are now independent
  • Performance improvements: memory-mapped file I/O (via ) eliminates heap copies of file contents; SIMD-accelerated line counting (via ); parallel detection pipeline uses to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #808)

Bug Fixes

  • Fixed to match jscpd v4's behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

Release v5.0.4

New Features

  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter

Bug Fixes

  • HTML reporter now outputs jscpd-report.html at the output_dir root

... (truncated)

Changelog

Sourced from jscpd's changelog.

5.0.9

New Features

  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5

Bug Fixes

  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #816

5.0.8

Bug Fixes

  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

5.0.7

Bug Fixes

  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

5.0.6

New Features

  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #808)

Bug Fixes

  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

... (truncated)

Commits
  • dcef743 release: cpd-v5.0.9
  • d330dda fix(#816): resolve platform package in nested node_modules
  • 2a7d19d release: cpd-v5.0.8
  • b75884d release: cpd-v5.0.7
  • 7507f9d fix: use project sizes without .git folders in benchmarks
  • 7d040b5 release: cpd-v5.0.6
  • fb8092f fix(ci): add setup-node with registry-url to publish-jscpd job
  • eda2252 release: cpd-v5.0.5
  • e5645ea feat(v5): add .jscpd.json path config support and update performance benchmarks
  • d21bb81 docs: reorganize documentation into docs/ folder, separate v4/v5 docs
  • Additional commits viewable in compare view

Updates prettier from 3.8.3 to 3.8.4

Release notes

Sourced from prettier's releases.

3.8.4

🔗 Changelog

Changelog

Sourced from prettier's changelog.

3.8.4

diff

Markdown: Fix blank lines between list items and nested sub-lists being removed in Markdown/MDX (#17746 by @​byplayer)

Prettier was removing blank lines between list items and their nested sub-lists, converting loose lists into tight lists and changing their semantic meaning.

<!-- Input -->
- a


b


c

d



<!-- Prettier 3.8.3 -->

a

b


c

d



<!-- Prettier 3.8.4 -->


a

b



c

d
Commits
  • 1c6ba55 Release 3.8.4
  • 4a673dc Fix blank lines between list items and nested sub-lists being removed in Mark...
  • 074aaed Replace main branch in changelog link with tags (#19054)
  • c22a003 Bump Prettier dependency to 3.8.3
  • 07bad1f Clean changelog_unreleased
  • See full diff in compare view

Updates tailwindcss from 4.3.0 to 4.3.1

Release notes

Sourced from tailwindcss's releases.

v4.3.1

Added

  • Add --silent option to suppress output in @tailwindcss/cli (#20100)

Fixed

  • Remove deprecation warnings by using Module#registerHooks instead of Module#register on Node 26+ (#20028)
  • Canonicalization: don't crash when plugin utilities throw for unsupported values (#20052)
  • Allow @apply to be used with CSS mixins (#19427)
  • Ensure not-* correctly negates @container queries, including style(…) queries (#20059)
  • Ensure drop-shadow-* color utilities work with custom shadow values containing calc(…) (#20080)
  • Fix 'Sourcemap is likely to be incorrect' warnings when using @tailwindcss/vite (#20103)
  • Ensure @tailwindcss/webpack can be installed in Rspack projects without requiring webpack as a peer dependency (#20027)
  • Canonicalization: don't suggest invalid calc(…) expressions (e.g. px-[calc(1rem+0px)] → px-[calc(1rem+0)]) (#20127)
  • Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. left-[99999px] → left-[99999px], not left-24999.75) (#20130)
  • Ensure @tailwindcss/cli in --watch mode recovers when a tracked dependency is deleted and restored (#20137)
  • Ensure standalone @tailwindcss/cli binaries are ignored when scanning for class candidates (#20139)
  • Ensure class candidates are extracted from Twig addClass(…) and removeClass(…) calls (#20198)
  • Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes (#19588)
  • Allow @variant to be used inside addBase (#19480)
  • Ensure @source globs with symlinks are preserved (#20203)
  • Ensure later @source rules can re-include files excluded by earlier @source not rules (#20203)
  • Upgrade: don't migrate empty class rules to invalid @utility rules (#20205)
  • Ensure transitions between inset-shadow-none and other inset shadows work correctly (#20208)
  • Ensure explicitly referenced @source directories are scanned even when ignored by git (#20214)
  • Ensure @source globs ending in **/* preserve dynamic path segments to avoid scanning too many files (#20217)
  • Canonicalization: don't fold calc(…) divisions when the result would require high precision (e.g. w-[calc(100%/3.5)] → w-[calc(100%/3.5)], not w-[28.571428571428573%]) (#20221)
  • Serve ESM type declarations to ESM importers of @tailwindcss/postcss (#20228)

Changed

  • Generate 0 instead of calc(var(--spacing) * 0) for spacing utilities like m-0 and left-0 (#20196)
  • Generate var(--spacing) instead of calc(var(--spacing) * 1) for spacing utilities like m-1 and left-1 (#20196)
Changelog

Sourced from tailwindcss's changelog.

[4.3.1] - 2026-06-12

Added

  • Add --silent option to suppress output in @tailwindcss/cli (#20100)

Fixed

  • Remove deprecation warnings by using Module#registerHooks instead of Module#register on Node 26+ (#20028)
  • Canonicalization: don't crash when plugin utilities throw for unsupported values (#20052)
  • Allow @apply to be used with CSS mixins (#19427)
  • Ensure not-* correctly negates @container queries, including style(…) queries (#20059)
  • Ensure drop-shadow-* color utilities work with custom shadow values containing calc(…) (#20080)
  • Fix 'Sourcemap is likely to be incorrect' warnings when using @tailwindcss/vite (#20103)
  • Ensure @tailwindcss/webpack can be installed in Rspack projects without requiring webpack as a peer dependency (#20027)
  • Canonicalization: don't suggest invalid calc(…) expressions (e.g. px-[calc(1rem+0px)] → px-[calc(1rem+0)]) (#20127)
  • Canonicalization: avoid suggesting large spacing-scale values for arbitrary lengths (e.g. left-[99999px] → left-[99999px], not left-24999.75) (#20130)
  • Ensure @tailwindcss/cli in --watch mode recovers when a tracked dependency is deleted and restored (#20137)
  • Ensure standalone @tailwindcss/cli binaries are ignored when scanning for class candidates (#20139)
  • Ensure class candidates are extracted from Twig addClass(…) and removeClass(…) calls (#20198)
  • Don't crash in the Ruby or Vue preprocessors when scanning files containing invalid UTF-8 bytes (#19588)
  • Allow @variant to be used inside addBase (#19480)
  • Ensure @source globs with symlinks are preserved (#20203)
  • Ensure later @source rules can re-include files excluded by earlier @source not rules (#20203)
  • Upgrade: don't migrate empty class rules to invalid @utility rules (#20205)
  • Ensure transitions between inset-shadow-none and other inset shadows work correctly (#20208)
  • Ensure explicitly referenced @source directories are scanned even when ignored by git (#20214)
  • Ensure @source globs ending in **/* preserve dynamic path segments to avoid scanning too many files (#20217)
  • Canonicalization: don't fold calc(…) divisions when the result would require high precision (e.g. w-[calc(100%/3.5)] → w-[calc(100%/3.5)], not w-[28.571428571428573%]) (#20221)
  • Serve ESM type declarations to ESM importers of @tailwindcss/postcss (#20228)

Changed

  • Generate 0 instead of calc(var(--spacing) * 0) for spacing utilities like m-0 and left-0 (#20196)
  • Generate var(--spacing) instead of calc(var(--spacing) * 1) for spacing utilities like m-1 and left-1 (#20196)
Commits

Updates typescript-eslint from 8.61.0 to 8.61.1

Release notes

Sourced from typescript-eslint's releases.

v8.61.1

8.61.1 (2026-06-15)

🩹 Fixes

  • eslint-plugin: [consistent-indexed-object-style] do not remove comments when fixing (#12396, #10577)
  • eslint-plugin: [no-unnecessary-type-assertion] avoid false positive for template literal expressions (#12281)
  • eslint-plugin: [no-unnecessary-type-assertion] wrap object literal in parens when removing TSTypeAssertion in arrow body (#12394, #12393)
  • eslint-plugin: [no-unnecessary-boolean-literal-compare] fix precedence bug in autofix (#12413)
  • eslint-plugin: [no-unnecessary-template-expression] respect ECMAScript line terminators (#12388)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from typescript-eslint's changelog.

8.61.1 (2026-06-15)

This was a version bump only for typescript-eslint to align it with other projects, there were no code changes.

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Commits

Updates vitest from 4.1.8 to 4.1.9

Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Jun 15, 2026
@dependabot
dependabot Bot requested a review from diegosouzapw as a code owner June 15, 2026 18:35
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Jun 15, 2026
@github-actions

github-actions Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

CI Coverage Report

  • Coverage job: success
  • PR test policy: success

Coverage artifact was not available for this run.

Bumps the development group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` |
| [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.3.0` | `4.3.1` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `25.9.2` | `25.9.3` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `16.2.7` | `16.2.9` |
| [jscpd](https://github.com/kucherenko/jscpd/tree/HEAD/rust/jscpd) | `4.2.5` | `5.0.9` |
| [prettier](https://github.com/prettier/prettier) | `3.8.3` | `3.8.4` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.61.0` | `8.61.1` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.8` | `4.1.9` |



Updates `@playwright/test` from 1.60.0 to 1.61.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](microsoft/playwright@v1.60.0...v1.61.0)

Updates `@tailwindcss/postcss` from 4.3.0 to 4.3.1
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/@tailwindcss-postcss)

Updates `@types/node` from 25.9.2 to 25.9.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint-config-next` from 16.2.7 to 16.2.9
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v16.2.9/packages/eslint-config-next)

Updates `jscpd` from 4.2.5 to 5.0.9
- [Release notes](https://github.com/kucherenko/jscpd/releases)
- [Changelog](https://github.com/kucherenko/jscpd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kucherenko/jscpd/commits/v5.0.9/rust/jscpd)

Updates `prettier` from 3.8.3 to 3.8.4
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](prettier/prettier@3.8.3...3.8.4)

Updates `tailwindcss` from 4.3.0 to 4.3.1
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/tailwindcss)

Updates `typescript-eslint` from 8.61.0 to 8.61.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.1/packages/typescript-eslint)

Updates `vitest` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/HEAD/packages/vitest)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.61.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: "@types/node"
  dependency-version: 25.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: eslint-config-next
  dependency-version: 16.2.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: jscpd
  dependency-version: 5.0.9
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: development
- dependency-name: prettier
  dependency-version: 3.8.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: tailwindcss
  dependency-version: 4.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: typescript-eslint
  dependency-version: 8.61.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
- dependency-name: vitest
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot changed the title deps: bump the development group with 9 updates deps: bump the development group across 1 directory with 9 updates Jun 16, 2026
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/development-2b6164e598 branch from ebee88d to e97d771 Compare June 16, 2026 04:05
@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.8.27 June 16, 2026 06:19
@diegosouzapw

Copy link
Copy Markdown
Owner

Closing this one. The jscpd bump (4.2.5 → 5.0.9) is intentionally not taken: jscpd v5 is a full Rust rewrite (native binary, no Node.js programmatic API) and our duplication gate scripts/check/check-duplication.mjs is deliberately pinned to jscpd@4 (it shells out to node_modules/.bin/jscpd and parses jscpd-report.json against a frozen baseline — the v5 binary changes the bin/report and would break or silently shift the ratchet). Migrating the gate to v5 is a separate, intentional effort, not a routine dependency bump. Adding an ignore rule for jscpd so this doesn't keep reopening. The rest of the dev group will come through future dependabot PRs without it.

@dependabot @github

dependabot Bot commented on behalf of github Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests.

To ignore these dependencies, configure ignore rules in dependabot.yml

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/development-2b6164e598 branch June 16, 2026 13:40
diegosouzapw added a commit that referenced this pull request Jun 16, 2026
…lication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from #3916.
diegosouzapw added a commit that referenced this pull request Jun 17, 2026
* chore(release): open v3.8.27 development cycle

* fix(security): polynomial ReDoS in comboAgentMiddleware regex (#3982)

* fix(security): eliminate polynomial ReDoS in comboAgentMiddleware <omniModel> regex (CodeQL js/polynomial-redos)

CACHE_TAG_PATTERN wrapped the tag in an unbounded `(?:\\n|\n|\r)*` prefix/suffix.
On an unanchored `.test()`/`.exec()` that is O(n²) on inputs with many newlines
(CodeQL js/polynomial-redos, alerts #612/#613). The surrounding runs are irrelevant
to detecting/capturing the tag, so the detection pattern now matches only the core
`<omniModel>([^<]+)</omniModel>`; the global strip pattern still consumes the
wrapping newlines (combo.ts streaming, #531) but BOUNDED ({0,16}) so it stays linear.

Behavior preserved: detection, model extraction, multi-tag stripping (#454) and
blank-line cleanup all unchanged (107 related tests green). Adds ReDoS-safety
regression tests (50k-newline inputs complete in <1ms).

* docs(changelog): add #3982 ReDoS fix to [3.8.27]

* ci(security): harden workflows — artipacked persist-credentials + cache-poisoning + SC2086 (#3965)

* Refine provider quota card display (#3969)

Integrated into release/v3.8.27

* feat: add sidebar group separator toggles (#3971)

Integrated into release/v3.8.27

* Gate control-plane proxy direct fallback (#3963)

Integrated into release/v3.8.27

* Capture actual upstream provider requests (#3941)

Integrated into release/v3.8.27

* ci(quality): flip require-tighten + osv + Trivy to blocking (v3.8.27 cycle-end) (#3984)

* fix(resilience): respect connection cooldown stored as numeric epoch (#3954) (#3995)

rate_limited_until is a TEXT column, but setConnectionRateLimitUntil (Antigravity full-quota path) persists a raw epoch number that SQLite coerces to a numeric string ("1781696905131.0"). The selection predicate isAccountUnavailable then did new Date("1781696905131.0") -> NaN, so the cooling connection was never skipped and the router kept dispatching to rate-limited accounts. Normalize numeric-epoch strings (and number/Date/ISO) via a shared cooldownUntilMs() helper in isAccountUnavailable / getEarliestRateLimitedUntil / filterAvailableAccounts / parseFutureDateMs. ISO behavior preserved.

* fix(providers): fetch live /models for LLM7 and BytePlus (#3976) (#3996)

llm7 and byteplus carry a real modelsUrl but were not classified by any live-fetch branch of the model-import route, so their hardcoded 4-entry registry catalog was served (source local_catalog) instead of the upstream catalog. Add both to NAMED_OPENAI_STYLE_PROVIDERS so the route probes <baseUrl>/models and serves the live list, falling back to the local catalog only on fetch failure.

* fix(dashboard): logs auto-refresh reads live visibility, not a stale mount ref (#3972) (#3997)

The auto-refresh interval gated each tick on visibleRef, seeded once at mount and updated only by a visibilitychange event. A tab mounted while document.visibilityState is 'hidden' (background load, bfcache, embedded/proxied webviews) with no later visibilitychange left the ref false forever, so the interval ticked but never fetched — only the manual button worked. Read the live document.visibilityState in the tick instead.

* feat(compression): add Indonesian caveman rules and language pack (#3975)

Integrated into release/v3.8.27

(cherry picked from commit c9b5b1a)

* fix(combo): shuffle strict-random fallback remainder to spread load (#3959) (#3998)

strict-random shuffled only the deck-selected slot 0 and left the fallback remainder in fixed priority order, so after a failing deck pick the chain always fell through to the same top-priority model — a persistently-failing model was retried on essentially every request and fallback load never spread across peers. Shuffle the remainder too (like the random strategy).

* Add provider auth visibility controls (#3953)

Integrated into release/v3.8.27

* fix(claude): forward client tool-search-tool anthropic-beta on the Claude OAuth path (#3974) (#3999)

The client-negotiated anthropic-beta: tool-search-tool-2025-10-19 was dropped on both Claude code paths (default executor rebuilt from static ANTHROPIC_BETA_CLAUDE_OAUTH; selectBetaFlags only read the client beta to gate thinking/effort), so claude.ai rejected deferred-tool requests with 400 'Tool reference not found'. Add an allowlist-merge (mergeClientAnthropicBeta) that unions the client's allowlisted betas into the outbound set on both paths, preserving #3415 (no forced thinking/effort).

* feat(providers): add model search filter to provider dashboard (#3950)

Integrated into release/v3.8.27

* fix(vision-bridge): force bridge for tokenrouter deepseek models (#3946)

Integrated into release/v3.8.27

* fix(executor): strip stream_options on non-streaming requests (#3884) (#4000)

Clients that send stream_options:{include_usage:true} regardless of stream (e.g. the OpenAI Python SDK) had it passed through on non-streaming calls; NVIDIA NIM rejected it with 400 'Stream options can only be defined when stream=True'. DefaultExecutor.transformRequest only injected/cleared stream_options on the streaming branch and never stripped a client-sent value when stream=false. Add a !stream strip branch; the streaming injection path is unchanged. Global to openai-compat providers.

* fix(qwen-web): cookie validation false-positive - check response body for user object (#3958)

Integrated into release/v3.8.27

* fix(db): persist backup retention days (#3970)

Integrated into release/v3.8.27

* 大量UI显示和i18n优化 (#3973)

Integrated into release/v3.8.27

* deps: bump the npm_and_yarn group across 1 directory with 2 updates (#3943)

Integrated into release/v3.8.27

* deps: bump form-data from 4.0.5 to 4.0.6 (#3944)

Integrated into release/v3.8.27

* deps: bump vite from 8.0.5 to 8.0.16 (#3942)

Integrated into release/v3.8.27

* chore(quality): re-baseline validation.ts 4407->4428 (#3958 qwen body-check)

The qwen-web validation body-check merged in #3958 pushed validation.ts past its
frozen size on the integrated release tip. Bump the baseline with justification;
no logic is separately extractable from the existing qwen-web validation branch.

* deps: bump the production group with 13 updates (#3915)

Integrated into release/v3.8.27 — low-risk group (playwright 1.60→1.61 minor + transitive patches; fumadocs-core 16.9→16.10 minor).

* chore(deps): ignore jscpd major bumps (v5 Rust rewrite breaks the duplication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from #3916.

* fix(perplexity-web): parse schematized diff_block stream so answers aren't empty (#4001)

Integrated into release/v3.8.27 — schematized diff_block parsing follow-up to #3938.

* refactor: modularize providerRegistry.ts into 159 individual provider plugins (#3993)

Modularize provider registry (#3594). Integrated into release/v3.8.27 after rebase + behavior-preservation verification (provider-consistency gate 159/232/0, typecheck, registry tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(registry): restore byteplus + mimocode dropped by #3993 modularization

The provider-registry modularization (#3993) was cut from a base predating the
byteplus (#3877) and mimocode (#3837) registry entries, so merging it silently
dropped both providers (getRegistryEntry returned undefined → validation reported
'not supported'). Re-add them as registry modules in the new structure; registered
count 159→161, provider-consistency 161/232/0.

Also align the pre-existing qwen-web validator test to #3958: since the validator
now requires a real `user` object in the 200 body, the mock must carry one.

* refactor: modularize schemas (non-stacked) (#3988)

Modularize validation schemas (#3594). Integrated into release/v3.8.27 after rebase (reconciled the merged hiddenSidebarGroupLabels #3971 + intelligenceSyncRequestSchema into the new modules) + behavior verification (typecheck, 195 schema/settings/validation tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(default-executor): honor custom providerSpecificData.baseUrl for OpenAI-format providers (#4002)

Integrated into release/v3.8.27 — honor custom providerSpecificData.baseUrl in DefaultExecutor (openai-format), tested.

* feat(openai): honor custom base URL in model discovery + complete openai/codex pricing (#4005)

Integrated into release/v3.8.27 — openai model-discovery honors custom base URL (SSRF-guarded) + pricing rows for new openai/codex models. Tested + baselines bumped.

* fix(live-ws): bridge sidecar events to dashboard (#4004)

Integrated into release/v3.8.27 — repair LiveWS sidecar (startup, same-origin /live-ws, main→sidecar compression.completed bridge, early-msg queue). Fixed the cookie-parse regex (\s) + added a focused unit test; baseline bumped for the non-blocking chatCore bridge.

* docs(troubleshooting): note MITM proxy cannot intercept Windows-host apps under WSL (#4003)

Integrated into release/v3.8.27 — MITM/WSL troubleshooting note.

* fix(repo): untrack accidentally-committed root node_modules symlink + gitignore it

A worktree node_modules symlink (-> the main checkout's node_modules) was staged by a
`git add -A` during the #3988 merge and committed into 05213ac. The symlink points
at the repo's own node_modules path, so checking it out turns the main checkout's
node_modules into a self-referential symlink (breaking tsx/all node ops). Untrack it and
add a root-anchored /node_modules ignore so the symlink form can't be re-committed (the
existing 'node_modules/' only matches directories).

* fix(quality): allowlist socks dep (declared by #4004, never allowlisted)

socks@^2.8.7 was added to package.json in #4004 (LiveWS sidecar, 0230213)
as a phantom-dep cleanup but never added to dependency-allowlist.json, so
check:deps has been red on the release tip ever since. socks is the standard
SOCKS proxy client (dep of fetch-socks), legitimate and years old.

* feat(sse): real LLMLingua-2 ONNX compression engine (stable) (#4014)

Integrated into release/v3.8.27.

Adjustments before merge:
- Synced with the current release tip (was 11 commits behind).
- Added the 3 LLMLingua-2 ONNX optional-runtime deps to dependency-allowlist.json
  (@atjsh/llmlingua-2, @tensorflow/tfjs, js-tiktoken) — the only gate that was red.
- socks was allowlisted directly on release (separate fix d7db5c7; it was declared
  by #4004 but never allowlisted, leaving check:deps red release-wide).

Verified locally: check:deps OK, file-size OK, public-creds OK, provider-consistency
161/232/0, typecheck:core clean, 24/24 LLMLingua tests pass. The only remaining Fast-QG
red is the pre-existing #3972 orphan test (request-logger-autorefresh-visibility-3972.test.tsx),
which is release-wide and unrelated to this PR.

* test(dashboard): rehome #3972 logs auto-refresh test so a runner collects it

tests/unit/request-logger-autorefresh-visibility-3972.test.tsx (added by #3972
via #3997) sat at the top level of tests/unit/ as a .tsx vitest test, which NO
runner collects: the node runner only globs *.test.ts, and test:vitest:ui only
runs tests/unit/ui. So the #3972 regression guard never executed in CI and
check:test-discovery was red release-wide. Move it under tests/unit/ui/ (the
collected vitest:ui path) and fix the relative import depth. Verified: the test
now runs and passes (2/2), and check:test-discovery is green.

* feat(compression): capture per-engine analytics (#3960) + Lite schema fix (#3952) (#4018)

Captures the net-new value from #3960 (per-engine breakdown analytics) and #3952 (Lite engine schema fix) onto release/v3.8.27. Fast QG green; 622/622 compression+analytics tests pass.

* fix(sse): guard model-less registry entries in getUnsupportedParams (mimocode) (#4015)

Real bugfix: guard model-less registry entries (mimocode) in getUnsupportedParams so handleChatCore no longer throws 'entry.models is not iterable' / reports 'All models failed' for unrelated requests. Includes a regression test. Fast QG green.

* feat(ci): Quality Gate v2 — Onda 0 + Onda 1 (gate flips, TIA, SAST, DAST-smoke, mutation infra) (#4016)

* docs(ops): add quality-gate assessment + replication playbook (Fase 9 foundation)

* feat(ci): flip oasdiff breaking-change gate to blocking (ratchet)

* docs(ops): deliver main branch-protection ruleset for owner to apply

* fix(ci): run typecheck:core in PR->release fast-gates (close fast-gates hole, part 1)

* perf(mutation): enable Stryker incremental mode + cache (scales the 60/80 rollout)

* feat(ci): commit CodeQL advanced config (security-extended), replacing default-setup

* feat(ci): version semgrep SAST workflow (owasp/secrets), advisory

* feat(quality): TIA test-impact map builder (import-graph; map built at runtime, gitignored)

* feat(quality): TIA impacted-test selector with run-all fail-safe

* fix(ci): run TIA-impacted unit tests in PR->release fast-gates (build map at runtime, fail-safe full)

* feat(ci): DAST-smoke per-PR (schemathesis subset + promptfoo injection-guard, blocking)

* fix(ci): unbreak Fase 9 PR CI (MDX frontmatter, CodeQL conflict, dast-smoke advisory)

- Add MDX frontmatter to docs/ops/{BRANCH_PROTECTION_MAIN,QUALITY_GATE_PLAYBOOK}.md.
  fumadocs rejects frontmatter-less docs -> 'npm run build' failed -> broke dast-smoke's
  build step (the release fast-gates never runs build, so this only surfaced on the PR).
- codeql.yml: workflow_dispatch-only until the owner switches repo CodeQL Default->Advanced
  (advanced configs cannot be processed while default setup is enabled; documented inline).
- dast-smoke.yml: job-level continue-on-error (advisory) so this brand-new gate matures
  before it blocks (repo convention: advisory -> blocking).

* ci(quality): make TIA unit-test step advisory until release test-debt is cleared

release/v3.8.27 carries ~17 pre-existing failing unit tests (budget #3537, apiKey
#3552, several Zod schemas, Puter/Qwen executors, mimocode entry, etc.) unrelated to
this PR — the new 'run tests on PR->release' gate surfaced them. Per the repo's
advisory->blocking convention, this step enters advisory (it still runs + reports)
so pre-existing debt doesn't block the gate program. typecheck:core stays blocking.
Flip to blocking (remove continue-on-error) once the release suite is green.

* fix(sse): preserve Kiro streaming finish_reason tool_calls (#3980) (#4025)

* fix(guardrails): preserve original image when vision-bridge describe fails (#4012) (#4026)

* feat(api): advertise combo capabilities on import surfaces (#3979) (#4027)

* feat(sse): delegated Anthropic Context Editing for Claude (clear_tool_uses) (#4021)

Opt-in Claude-only delegated compression: injects context_management.clear_tool_uses_20250919 at the Claude pre-serialization chokepoint (composes with clear_thinking, thinking first), threaded via ExecuteInput from handleChatCore. Pure edit-builder + 11 tests (7 unit + 4 e2e fetch-capture). Beta context-management-2025-06-27 already advertised; allowlist done. Telemetry/400-fallback/claude-web coverage deferred.

* fix(opencode): map x-session-affinity to x-opencode-session for custom providers (#4022) (#4028)

* fix(dashboard): Playground Compare tab loading + HTTP method guard (#4024)

randomUUID non-HTTPS fallback + static CompareTab import; raw HTTP TRACE->405 method guard wired into dev + standalone servers. Integrated into release/v3.8.27.

* refactor(dashboard): settings UI layout + API Keys naming (#4020)

Presentation/relabel refactor of the Settings dashboard (API Manager -> API Keys), card relocations, Toggle adoption, present-but-disabled engine steps. Auth-file changes are string/comment-only (no behavior change). Integrated into release/v3.8.27.

* fix: restore unit regressions dropped by lossy schema/registry modularizations (#4030)

Restores schema fields (combo reasoningTokenBuffer, budget-0 #3537, openrouter preset, proxy family #3777, resilience degradation/providerCooldown), qwen-web v2 endpoint+catalog, mimocode models key — all dropped by #3988/#3993 — and aligns 3 tests to #3941/#3993. Verified: 8 failing regression tests on release tip -> 131/131 green on this branch. Integrated into release/v3.8.27.

* fix(api): return 400 (not 500) for malformed JSON on /api/auth/login (#4031)

Wrap request.json() so a malformed/non-JSON login body returns a structured 400 instead of falling through to the 500 catch. Fixes the schemathesis high-risk-endpoint DAST finding (verified: schemathesis step now passes). +TDD test. Integrated into release/v3.8.27.

* feat(dashboard): real circuit-breaker state in the Combo Live cascade (U1b) (#4029)

Overlays real provider circuit-breaker state (GET /api/monitoring/health) onto the Combo Live cascade as a 'CB: OPEN · 41s' badge. Pure enrichRunWithBreakers + fail-soft useProviderBreakerHealth poll; graceful when health is absent. +13 tests. Integrated into release/v3.8.27.

* Fix promptfoo security assertion parsing (#4032)

* chore(deps): dependabot security bumps + drop unused gray-matter (#4036)

Integrated into release/v3.8.27 — dependabot security bumps (form-data/js-yaml/protobufjs/dompurify/hono) + drop unused gray-matter. Unblocks the npm audit:deps gate (Lint) branch-wide.

* fix(ci): scope TIA to node:test unit files only (mirror test:unit glob) (#4035)

Integrated into release/v3.8.27 — scopes the advisory TIA step to the test:unit node:test glob, fixing the 99 false failures. +4 TDD.

* Refine compression settings, storage labels, and sidebar grouping (#4033)

Integrated into release/v3.8.27 — relocate Token Saver into Compression Settings (controlled component), reorder Security/Authz tabs, storage labels + i18n relabel. Thanks @rdself!

* [codex] add per-key local usage command (#4034)

Integrated into release/v3.8.27 — per-key local @@om-usage command (cached quota, no upstream routing). Rebased onto modularized schemas/keys.ts + file-size rebaseline. Thanks @Witroch4!

* chore(release): reconcile v3.8.27 CHANGELOG + i18n mirrors

* ci(quality): unblock v3.8.27 release gates (zizmor pin + test-masking allowlist)

- zizmor ratchet (151→139, no regression): SHA-pin every action ref ADDED this
  cycle — codeql/dast-smoke/semgrep (3 new workflows) + trivy-action (docker-publish)
  + actions/cache (nightly-mutation). Pre-existing tag refs keep the repo convention.
- test-masking: add config/quality/test-masking-allowlist.json + allowlist support in
  check-test-masking.mjs (exempts ONLY the net-assert-reduction signal; tautology/skip/
  deletion still fire). Allowlists 2 verified-legitimate reductions:
  appearance-widget-settings-schema (#4033 removed showTokenSaverOnEndpoint field) and
  dashboard-shell-tabs (#3973 tabs→redirect refactor, asserts replaced). +4 gate tests.

* test(quality): reword test-masking self-test comments to avoid literal masking patterns

The added allowlist-test comments contained the literal strings 'assert.ok(true)' and
'.skip' which the masking detector's own regexes match as text — making the gate flag
its own test file (net +1 tautology/skip/extended-tautology vs main). Reworded to plain
prose ('a new tautology', 'a new skip marker'); test logic unchanged (24/24 pass).

* fix(quality): unblock v3.8.27 release — align 3 stale tests + restore modularized settings-schema parity

Release-PR full CI surfaced 3 deterministic test failures (no live product regression),
all stale vs legitimate cycle changes:

- settings-schema parity (#3988): the modularized updateSettingsSchema barrel
  (schemas/settings.ts) had diverged from the canonical settingsSchemas.ts (45 vs 85
  fields — 40 dropped + 6 extra), a lossy-modularization dead-code copy. Re-export from
  the canonical source so the barrel can never diverge again (runtime already uses
  canonical). Parity test now passes.
- api-manager permissions modal: #4034 added a 4th self-service switch (per-key usage
  allowance); a11y invariant (every switch type="button") still holds. Updated the
  static count 3 -> 4.
- pack-artifact policy: dist/http-method-guard.cjs became a required runtime path;
  added it to the test's expected missing-paths list.

Also documents the gate gap for Fase 9 (QUALITY_GATE_PLAYBOOK Parte 6): G1 run the
deterministic unit layer + test-masking on PR->release (not just PR->main), G2 a
modularization-parity gate (would have caught the #3988 drop at its PR), G3 flake
quarantine. Env flakes (LiveWS startup timeout, integration server-startup cascade)
are pre-existing/CI-env, triaged separately.

---------

Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Veier04 <118300867+Veier04@users.noreply.github.com>
Co-authored-by: Felipe Sartori <felipesartori.ti@gmail.com>
Co-authored-by: WormAlien <164898390+WormAlien@users.noreply.github.com>
Co-authored-by: thezukiru <121331256+thezukiru@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Demiurge The Single <megamen932@gmail.com>
Co-authored-by: Witroch4 <witalo_rocha@hotmail.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
* chore(release): open v3.8.27 development cycle

* fix(security): polynomial ReDoS in comboAgentMiddleware regex (diegosouzapw#3982)

* fix(security): eliminate polynomial ReDoS in comboAgentMiddleware <omniModel> regex (CodeQL js/polynomial-redos)

CACHE_TAG_PATTERN wrapped the tag in an unbounded `(?:\\n|\n|\r)*` prefix/suffix.
On an unanchored `.test()`/`.exec()` that is O(n²) on inputs with many newlines
(CodeQL js/polynomial-redos, alerts diegosouzapw#612/diegosouzapw#613). The surrounding runs are irrelevant
to detecting/capturing the tag, so the detection pattern now matches only the core
`<omniModel>([^<]+)</omniModel>`; the global strip pattern still consumes the
wrapping newlines (combo.ts streaming, diegosouzapw#531) but BOUNDED ({0,16}) so it stays linear.

Behavior preserved: detection, model extraction, multi-tag stripping (diegosouzapw#454) and
blank-line cleanup all unchanged (107 related tests green). Adds ReDoS-safety
regression tests (50k-newline inputs complete in <1ms).

* docs(changelog): add diegosouzapw#3982 ReDoS fix to [3.8.27]

* ci(security): harden workflows — artipacked persist-credentials + cache-poisoning + SC2086 (diegosouzapw#3965)

* Refine provider quota card display (diegosouzapw#3969)

Integrated into release/v3.8.27

* feat: add sidebar group separator toggles (diegosouzapw#3971)

Integrated into release/v3.8.27

* Gate control-plane proxy direct fallback (diegosouzapw#3963)

Integrated into release/v3.8.27

* Capture actual upstream provider requests (diegosouzapw#3941)

Integrated into release/v3.8.27

* ci(quality): flip require-tighten + osv + Trivy to blocking (v3.8.27 cycle-end) (diegosouzapw#3984)

* fix(resilience): respect connection cooldown stored as numeric epoch (diegosouzapw#3954) (diegosouzapw#3995)

rate_limited_until is a TEXT column, but setConnectionRateLimitUntil (Antigravity full-quota path) persists a raw epoch number that SQLite coerces to a numeric string ("1781696905131.0"). The selection predicate isAccountUnavailable then did new Date("1781696905131.0") -> NaN, so the cooling connection was never skipped and the router kept dispatching to rate-limited accounts. Normalize numeric-epoch strings (and number/Date/ISO) via a shared cooldownUntilMs() helper in isAccountUnavailable / getEarliestRateLimitedUntil / filterAvailableAccounts / parseFutureDateMs. ISO behavior preserved.

* fix(providers): fetch live /models for LLM7 and BytePlus (diegosouzapw#3976) (diegosouzapw#3996)

llm7 and byteplus carry a real modelsUrl but were not classified by any live-fetch branch of the model-import route, so their hardcoded 4-entry registry catalog was served (source local_catalog) instead of the upstream catalog. Add both to NAMED_OPENAI_STYLE_PROVIDERS so the route probes <baseUrl>/models and serves the live list, falling back to the local catalog only on fetch failure.

* fix(dashboard): logs auto-refresh reads live visibility, not a stale mount ref (diegosouzapw#3972) (diegosouzapw#3997)

The auto-refresh interval gated each tick on visibleRef, seeded once at mount and updated only by a visibilitychange event. A tab mounted while document.visibilityState is 'hidden' (background load, bfcache, embedded/proxied webviews) with no later visibilitychange left the ref false forever, so the interval ticked but never fetched — only the manual button worked. Read the live document.visibilityState in the tick instead.

* feat(compression): add Indonesian caveman rules and language pack (diegosouzapw#3975)

Integrated into release/v3.8.27

(cherry picked from commit 9269c4b)

* fix(combo): shuffle strict-random fallback remainder to spread load (diegosouzapw#3959) (diegosouzapw#3998)

strict-random shuffled only the deck-selected slot 0 and left the fallback remainder in fixed priority order, so after a failing deck pick the chain always fell through to the same top-priority model — a persistently-failing model was retried on essentially every request and fallback load never spread across peers. Shuffle the remainder too (like the random strategy).

* Add provider auth visibility controls (diegosouzapw#3953)

Integrated into release/v3.8.27

* fix(claude): forward client tool-search-tool anthropic-beta on the Claude OAuth path (diegosouzapw#3974) (diegosouzapw#3999)

The client-negotiated anthropic-beta: tool-search-tool-2025-10-19 was dropped on both Claude code paths (default executor rebuilt from static ANTHROPIC_BETA_CLAUDE_OAUTH; selectBetaFlags only read the client beta to gate thinking/effort), so claude.ai rejected deferred-tool requests with 400 'Tool reference not found'. Add an allowlist-merge (mergeClientAnthropicBeta) that unions the client's allowlisted betas into the outbound set on both paths, preserving diegosouzapw#3415 (no forced thinking/effort).

* feat(providers): add model search filter to provider dashboard (diegosouzapw#3950)

Integrated into release/v3.8.27

* fix(vision-bridge): force bridge for tokenrouter deepseek models (diegosouzapw#3946)

Integrated into release/v3.8.27

* fix(executor): strip stream_options on non-streaming requests (diegosouzapw#3884) (diegosouzapw#4000)

Clients that send stream_options:{include_usage:true} regardless of stream (e.g. the OpenAI Python SDK) had it passed through on non-streaming calls; NVIDIA NIM rejected it with 400 'Stream options can only be defined when stream=True'. DefaultExecutor.transformRequest only injected/cleared stream_options on the streaming branch and never stripped a client-sent value when stream=false. Add a !stream strip branch; the streaming injection path is unchanged. Global to openai-compat providers.

* fix(qwen-web): cookie validation false-positive - check response body for user object (diegosouzapw#3958)

Integrated into release/v3.8.27

* fix(db): persist backup retention days (diegosouzapw#3970)

Integrated into release/v3.8.27

* 大量UI显示和i18n优化 (diegosouzapw#3973)

Integrated into release/v3.8.27

* deps: bump the npm_and_yarn group across 1 directory with 2 updates (diegosouzapw#3943)

Integrated into release/v3.8.27

* deps: bump form-data from 4.0.5 to 4.0.6 (diegosouzapw#3944)

Integrated into release/v3.8.27

* deps: bump vite from 8.0.5 to 8.0.16 (diegosouzapw#3942)

Integrated into release/v3.8.27

* chore(quality): re-baseline validation.ts 4407->4428 (diegosouzapw#3958 qwen body-check)

The qwen-web validation body-check merged in diegosouzapw#3958 pushed validation.ts past its
frozen size on the integrated release tip. Bump the baseline with justification;
no logic is separately extractable from the existing qwen-web validation branch.

* deps: bump the production group with 13 updates (diegosouzapw#3915)

Integrated into release/v3.8.27 — low-risk group (playwright 1.60→1.61 minor + transitive patches; fumadocs-core 16.9→16.10 minor).

* chore(deps): ignore jscpd major bumps (v5 Rust rewrite breaks the duplication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from diegosouzapw#3916.

* fix(perplexity-web): parse schematized diff_block stream so answers aren't empty (diegosouzapw#4001)

Integrated into release/v3.8.27 — schematized diff_block parsing follow-up to diegosouzapw#3938.

* refactor: modularize providerRegistry.ts into 159 individual provider plugins (diegosouzapw#3993)

Modularize provider registry (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase + behavior-preservation verification (provider-consistency gate 159/232/0, typecheck, registry tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(registry): restore byteplus + mimocode dropped by diegosouzapw#3993 modularization

The provider-registry modularization (diegosouzapw#3993) was cut from a base predating the
byteplus (diegosouzapw#3877) and mimocode (diegosouzapw#3837) registry entries, so merging it silently
dropped both providers (getRegistryEntry returned undefined → validation reported
'not supported'). Re-add them as registry modules in the new structure; registered
count 159→161, provider-consistency 161/232/0.

Also align the pre-existing qwen-web validator test to diegosouzapw#3958: since the validator
now requires a real `user` object in the 200 body, the mock must carry one.

* refactor: modularize schemas (non-stacked) (diegosouzapw#3988)

Modularize validation schemas (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase (reconciled the merged hiddenSidebarGroupLabels diegosouzapw#3971 + intelligenceSyncRequestSchema into the new modules) + behavior verification (typecheck, 195 schema/settings/validation tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(default-executor): honor custom providerSpecificData.baseUrl for OpenAI-format providers (diegosouzapw#4002)

Integrated into release/v3.8.27 — honor custom providerSpecificData.baseUrl in DefaultExecutor (openai-format), tested.

* feat(openai): honor custom base URL in model discovery + complete openai/codex pricing (diegosouzapw#4005)

Integrated into release/v3.8.27 — openai model-discovery honors custom base URL (SSRF-guarded) + pricing rows for new openai/codex models. Tested + baselines bumped.

* fix(live-ws): bridge sidecar events to dashboard (diegosouzapw#4004)

Integrated into release/v3.8.27 — repair LiveWS sidecar (startup, same-origin /live-ws, main→sidecar compression.completed bridge, early-msg queue). Fixed the cookie-parse regex (\s) + added a focused unit test; baseline bumped for the non-blocking chatCore bridge.

* docs(troubleshooting): note MITM proxy cannot intercept Windows-host apps under WSL (diegosouzapw#4003)

Integrated into release/v3.8.27 — MITM/WSL troubleshooting note.

* fix(repo): untrack accidentally-committed root node_modules symlink + gitignore it

A worktree node_modules symlink (-> the main checkout's node_modules) was staged by a
`git add -A` during the diegosouzapw#3988 merge and committed into c0b0436. The symlink points
at the repo's own node_modules path, so checking it out turns the main checkout's
node_modules into a self-referential symlink (breaking tsx/all node ops). Untrack it and
add a root-anchored /node_modules ignore so the symlink form can't be re-committed (the
existing 'node_modules/' only matches directories).

* fix(quality): allowlist socks dep (declared by diegosouzapw#4004, never allowlisted)

socks@^2.8.7 was added to package.json in diegosouzapw#4004 (LiveWS sidecar, 4e5d908)
as a phantom-dep cleanup but never added to dependency-allowlist.json, so
check:deps has been red on the release tip ever since. socks is the standard
SOCKS proxy client (dep of fetch-socks), legitimate and years old.

* feat(sse): real LLMLingua-2 ONNX compression engine (stable) (diegosouzapw#4014)

Integrated into release/v3.8.27.

Adjustments before merge:
- Synced with the current release tip (was 11 commits behind).
- Added the 3 LLMLingua-2 ONNX optional-runtime deps to dependency-allowlist.json
  (@atjsh/llmlingua-2, @tensorflow/tfjs, js-tiktoken) — the only gate that was red.
- socks was allowlisted directly on release (separate fix ded61fd; it was declared
  by diegosouzapw#4004 but never allowlisted, leaving check:deps red release-wide).

Verified locally: check:deps OK, file-size OK, public-creds OK, provider-consistency
161/232/0, typecheck:core clean, 24/24 LLMLingua tests pass. The only remaining Fast-QG
red is the pre-existing diegosouzapw#3972 orphan test (request-logger-autorefresh-visibility-3972.test.tsx),
which is release-wide and unrelated to this PR.

* test(dashboard): rehome diegosouzapw#3972 logs auto-refresh test so a runner collects it

tests/unit/request-logger-autorefresh-visibility-3972.test.tsx (added by diegosouzapw#3972
via diegosouzapw#3997) sat at the top level of tests/unit/ as a .tsx vitest test, which NO
runner collects: the node runner only globs *.test.ts, and test:vitest:ui only
runs tests/unit/ui. So the diegosouzapw#3972 regression guard never executed in CI and
check:test-discovery was red release-wide. Move it under tests/unit/ui/ (the
collected vitest:ui path) and fix the relative import depth. Verified: the test
now runs and passes (2/2), and check:test-discovery is green.

* feat(compression): capture per-engine analytics (diegosouzapw#3960) + Lite schema fix (diegosouzapw#3952) (diegosouzapw#4018)

Captures the net-new value from diegosouzapw#3960 (per-engine breakdown analytics) and diegosouzapw#3952 (Lite engine schema fix) onto release/v3.8.27. Fast QG green; 622/622 compression+analytics tests pass.

* fix(sse): guard model-less registry entries in getUnsupportedParams (mimocode) (diegosouzapw#4015)

Real bugfix: guard model-less registry entries (mimocode) in getUnsupportedParams so handleChatCore no longer throws 'entry.models is not iterable' / reports 'All models failed' for unrelated requests. Includes a regression test. Fast QG green.

* feat(ci): Quality Gate v2 — Onda 0 + Onda 1 (gate flips, TIA, SAST, DAST-smoke, mutation infra) (diegosouzapw#4016)

* docs(ops): add quality-gate assessment + replication playbook (Fase 9 foundation)

* feat(ci): flip oasdiff breaking-change gate to blocking (ratchet)

* docs(ops): deliver main branch-protection ruleset for owner to apply

* fix(ci): run typecheck:core in PR->release fast-gates (close fast-gates hole, part 1)

* perf(mutation): enable Stryker incremental mode + cache (scales the 60/80 rollout)

* feat(ci): commit CodeQL advanced config (security-extended), replacing default-setup

* feat(ci): version semgrep SAST workflow (owasp/secrets), advisory

* feat(quality): TIA test-impact map builder (import-graph; map built at runtime, gitignored)

* feat(quality): TIA impacted-test selector with run-all fail-safe

* fix(ci): run TIA-impacted unit tests in PR->release fast-gates (build map at runtime, fail-safe full)

* feat(ci): DAST-smoke per-PR (schemathesis subset + promptfoo injection-guard, blocking)

* fix(ci): unbreak Fase 9 PR CI (MDX frontmatter, CodeQL conflict, dast-smoke advisory)

- Add MDX frontmatter to docs/ops/{BRANCH_PROTECTION_MAIN,QUALITY_GATE_PLAYBOOK}.md.
  fumadocs rejects frontmatter-less docs -> 'npm run build' failed -> broke dast-smoke's
  build step (the release fast-gates never runs build, so this only surfaced on the PR).
- codeql.yml: workflow_dispatch-only until the owner switches repo CodeQL Default->Advanced
  (advanced configs cannot be processed while default setup is enabled; documented inline).
- dast-smoke.yml: job-level continue-on-error (advisory) so this brand-new gate matures
  before it blocks (repo convention: advisory -> blocking).

* ci(quality): make TIA unit-test step advisory until release test-debt is cleared

release/v3.8.27 carries ~17 pre-existing failing unit tests (budget diegosouzapw#3537, apiKey
diegosouzapw#3552, several Zod schemas, Puter/Qwen executors, mimocode entry, etc.) unrelated to
this PR — the new 'run tests on PR->release' gate surfaced them. Per the repo's
advisory->blocking convention, this step enters advisory (it still runs + reports)
so pre-existing debt doesn't block the gate program. typecheck:core stays blocking.
Flip to blocking (remove continue-on-error) once the release suite is green.

* fix(sse): preserve Kiro streaming finish_reason tool_calls (diegosouzapw#3980) (diegosouzapw#4025)

* fix(guardrails): preserve original image when vision-bridge describe fails (diegosouzapw#4012) (diegosouzapw#4026)

* feat(api): advertise combo capabilities on import surfaces (diegosouzapw#3979) (diegosouzapw#4027)

* feat(sse): delegated Anthropic Context Editing for Claude (clear_tool_uses) (diegosouzapw#4021)

Opt-in Claude-only delegated compression: injects context_management.clear_tool_uses_20250919 at the Claude pre-serialization chokepoint (composes with clear_thinking, thinking first), threaded via ExecuteInput from handleChatCore. Pure edit-builder + 11 tests (7 unit + 4 e2e fetch-capture). Beta context-management-2025-06-27 already advertised; allowlist done. Telemetry/400-fallback/claude-web coverage deferred.

* fix(opencode): map x-session-affinity to x-opencode-session for custom providers (diegosouzapw#4022) (diegosouzapw#4028)

* fix(dashboard): Playground Compare tab loading + HTTP method guard (diegosouzapw#4024)

randomUUID non-HTTPS fallback + static CompareTab import; raw HTTP TRACE->405 method guard wired into dev + standalone servers. Integrated into release/v3.8.27.

* refactor(dashboard): settings UI layout + API Keys naming (diegosouzapw#4020)

Presentation/relabel refactor of the Settings dashboard (API Manager -> API Keys), card relocations, Toggle adoption, present-but-disabled engine steps. Auth-file changes are string/comment-only (no behavior change). Integrated into release/v3.8.27.

* fix: restore unit regressions dropped by lossy schema/registry modularizations (diegosouzapw#4030)

Restores schema fields (combo reasoningTokenBuffer, budget-0 diegosouzapw#3537, openrouter preset, proxy family diegosouzapw#3777, resilience degradation/providerCooldown), qwen-web v2 endpoint+catalog, mimocode models key — all dropped by diegosouzapw#3988/diegosouzapw#3993 — and aligns 3 tests to diegosouzapw#3941/diegosouzapw#3993. Verified: 8 failing regression tests on release tip -> 131/131 green on this branch. Integrated into release/v3.8.27.

* fix(api): return 400 (not 500) for malformed JSON on /api/auth/login (diegosouzapw#4031)

Wrap request.json() so a malformed/non-JSON login body returns a structured 400 instead of falling through to the 500 catch. Fixes the schemathesis high-risk-endpoint DAST finding (verified: schemathesis step now passes). +TDD test. Integrated into release/v3.8.27.

* feat(dashboard): real circuit-breaker state in the Combo Live cascade (U1b) (diegosouzapw#4029)

Overlays real provider circuit-breaker state (GET /api/monitoring/health) onto the Combo Live cascade as a 'CB: OPEN · 41s' badge. Pure enrichRunWithBreakers + fail-soft useProviderBreakerHealth poll; graceful when health is absent. +13 tests. Integrated into release/v3.8.27.

* Fix promptfoo security assertion parsing (diegosouzapw#4032)

* chore(deps): dependabot security bumps + drop unused gray-matter (diegosouzapw#4036)

Integrated into release/v3.8.27 — dependabot security bumps (form-data/js-yaml/protobufjs/dompurify/hono) + drop unused gray-matter. Unblocks the npm audit:deps gate (Lint) branch-wide.

* fix(ci): scope TIA to node:test unit files only (mirror test:unit glob) (diegosouzapw#4035)

Integrated into release/v3.8.27 — scopes the advisory TIA step to the test:unit node:test glob, fixing the 99 false failures. +4 TDD.

* Refine compression settings, storage labels, and sidebar grouping (diegosouzapw#4033)

Integrated into release/v3.8.27 — relocate Token Saver into Compression Settings (controlled component), reorder Security/Authz tabs, storage labels + i18n relabel. Thanks @rdself!

* [codex] add per-key local usage command (diegosouzapw#4034)

Integrated into release/v3.8.27 — per-key local @@om-usage command (cached quota, no upstream routing). Rebased onto modularized schemas/keys.ts + file-size rebaseline. Thanks @Witroch4!

* chore(release): reconcile v3.8.27 CHANGELOG + i18n mirrors

* ci(quality): unblock v3.8.27 release gates (zizmor pin + test-masking allowlist)

- zizmor ratchet (151→139, no regression): SHA-pin every action ref ADDED this
  cycle — codeql/dast-smoke/semgrep (3 new workflows) + trivy-action (docker-publish)
  + actions/cache (nightly-mutation). Pre-existing tag refs keep the repo convention.
- test-masking: add config/quality/test-masking-allowlist.json + allowlist support in
  check-test-masking.mjs (exempts ONLY the net-assert-reduction signal; tautology/skip/
  deletion still fire). Allowlists 2 verified-legitimate reductions:
  appearance-widget-settings-schema (diegosouzapw#4033 removed showTokenSaverOnEndpoint field) and
  dashboard-shell-tabs (diegosouzapw#3973 tabs→redirect refactor, asserts replaced). +4 gate tests.

* test(quality): reword test-masking self-test comments to avoid literal masking patterns

The added allowlist-test comments contained the literal strings 'assert.ok(true)' and
'.skip' which the masking detector's own regexes match as text — making the gate flag
its own test file (net +1 tautology/skip/extended-tautology vs main). Reworded to plain
prose ('a new tautology', 'a new skip marker'); test logic unchanged (24/24 pass).

* fix(quality): unblock v3.8.27 release — align 3 stale tests + restore modularized settings-schema parity

Release-PR full CI surfaced 3 deterministic test failures (no live product regression),
all stale vs legitimate cycle changes:

- settings-schema parity (diegosouzapw#3988): the modularized updateSettingsSchema barrel
  (schemas/settings.ts) had diverged from the canonical settingsSchemas.ts (45 vs 85
  fields — 40 dropped + 6 extra), a lossy-modularization dead-code copy. Re-export from
  the canonical source so the barrel can never diverge again (runtime already uses
  canonical). Parity test now passes.
- api-manager permissions modal: diegosouzapw#4034 added a 4th self-service switch (per-key usage
  allowance); a11y invariant (every switch type="button") still holds. Updated the
  static count 3 -> 4.
- pack-artifact policy: dist/http-method-guard.cjs became a required runtime path;
  added it to the test's expected missing-paths list.

Also documents the gate gap for Fase 9 (QUALITY_GATE_PLAYBOOK Parte 6): G1 run the
deterministic unit layer + test-masking on PR->release (not just PR->main), G2 a
modularization-parity gate (would have caught the diegosouzapw#3988 drop at its PR), G3 flake
quarantine. Env flakes (LiveWS startup timeout, integration server-startup cascade)
are pre-existing/CI-env, triaged separately.

---------

Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Veier04 <118300867+Veier04@users.noreply.github.com>
Co-authored-by: Felipe Sartori <felipesartori.ti@gmail.com>
Co-authored-by: WormAlien <164898390+WormAlien@users.noreply.github.com>
Co-authored-by: thezukiru <121331256+thezukiru@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Demiurge The Single <megamen932@gmail.com>
Co-authored-by: Witroch4 <witalo_rocha@hotmail.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
* chore(release): open v3.8.27 development cycle

* fix(security): polynomial ReDoS in comboAgentMiddleware regex (diegosouzapw#3982)

* fix(security): eliminate polynomial ReDoS in comboAgentMiddleware <omniModel> regex (CodeQL js/polynomial-redos)

CACHE_TAG_PATTERN wrapped the tag in an unbounded `(?:\\n|\n|\r)*` prefix/suffix.
On an unanchored `.test()`/`.exec()` that is O(n²) on inputs with many newlines
(CodeQL js/polynomial-redos, alerts diegosouzapw#612/diegosouzapw#613). The surrounding runs are irrelevant
to detecting/capturing the tag, so the detection pattern now matches only the core
`<omniModel>([^<]+)</omniModel>`; the global strip pattern still consumes the
wrapping newlines (combo.ts streaming, diegosouzapw#531) but BOUNDED ({0,16}) so it stays linear.

Behavior preserved: detection, model extraction, multi-tag stripping (diegosouzapw#454) and
blank-line cleanup all unchanged (107 related tests green). Adds ReDoS-safety
regression tests (50k-newline inputs complete in <1ms).

* docs(changelog): add diegosouzapw#3982 ReDoS fix to [3.8.27]

* ci(security): harden workflows — artipacked persist-credentials + cache-poisoning + SC2086 (diegosouzapw#3965)

* Refine provider quota card display (diegosouzapw#3969)

Integrated into release/v3.8.27

* feat: add sidebar group separator toggles (diegosouzapw#3971)

Integrated into release/v3.8.27

* Gate control-plane proxy direct fallback (diegosouzapw#3963)

Integrated into release/v3.8.27

* Capture actual upstream provider requests (diegosouzapw#3941)

Integrated into release/v3.8.27

* ci(quality): flip require-tighten + osv + Trivy to blocking (v3.8.27 cycle-end) (diegosouzapw#3984)

* fix(resilience): respect connection cooldown stored as numeric epoch (diegosouzapw#3954) (diegosouzapw#3995)

rate_limited_until is a TEXT column, but setConnectionRateLimitUntil (Antigravity full-quota path) persists a raw epoch number that SQLite coerces to a numeric string ("1781696905131.0"). The selection predicate isAccountUnavailable then did new Date("1781696905131.0") -> NaN, so the cooling connection was never skipped and the router kept dispatching to rate-limited accounts. Normalize numeric-epoch strings (and number/Date/ISO) via a shared cooldownUntilMs() helper in isAccountUnavailable / getEarliestRateLimitedUntil / filterAvailableAccounts / parseFutureDateMs. ISO behavior preserved.

* fix(providers): fetch live /models for LLM7 and BytePlus (diegosouzapw#3976) (diegosouzapw#3996)

llm7 and byteplus carry a real modelsUrl but were not classified by any live-fetch branch of the model-import route, so their hardcoded 4-entry registry catalog was served (source local_catalog) instead of the upstream catalog. Add both to NAMED_OPENAI_STYLE_PROVIDERS so the route probes <baseUrl>/models and serves the live list, falling back to the local catalog only on fetch failure.

* fix(dashboard): logs auto-refresh reads live visibility, not a stale mount ref (diegosouzapw#3972) (diegosouzapw#3997)

The auto-refresh interval gated each tick on visibleRef, seeded once at mount and updated only by a visibilitychange event. A tab mounted while document.visibilityState is 'hidden' (background load, bfcache, embedded/proxied webviews) with no later visibilitychange left the ref false forever, so the interval ticked but never fetched — only the manual button worked. Read the live document.visibilityState in the tick instead.

* feat(compression): add Indonesian caveman rules and language pack (diegosouzapw#3975)

Integrated into release/v3.8.27

(cherry picked from commit c9b5b1a)

* fix(combo): shuffle strict-random fallback remainder to spread load (diegosouzapw#3959) (diegosouzapw#3998)

strict-random shuffled only the deck-selected slot 0 and left the fallback remainder in fixed priority order, so after a failing deck pick the chain always fell through to the same top-priority model — a persistently-failing model was retried on essentially every request and fallback load never spread across peers. Shuffle the remainder too (like the random strategy).

* Add provider auth visibility controls (diegosouzapw#3953)

Integrated into release/v3.8.27

* fix(claude): forward client tool-search-tool anthropic-beta on the Claude OAuth path (diegosouzapw#3974) (diegosouzapw#3999)

The client-negotiated anthropic-beta: tool-search-tool-2025-10-19 was dropped on both Claude code paths (default executor rebuilt from static ANTHROPIC_BETA_CLAUDE_OAUTH; selectBetaFlags only read the client beta to gate thinking/effort), so claude.ai rejected deferred-tool requests with 400 'Tool reference not found'. Add an allowlist-merge (mergeClientAnthropicBeta) that unions the client's allowlisted betas into the outbound set on both paths, preserving diegosouzapw#3415 (no forced thinking/effort).

* feat(providers): add model search filter to provider dashboard (diegosouzapw#3950)

Integrated into release/v3.8.27

* fix(vision-bridge): force bridge for tokenrouter deepseek models (diegosouzapw#3946)

Integrated into release/v3.8.27

* fix(executor): strip stream_options on non-streaming requests (diegosouzapw#3884) (diegosouzapw#4000)

Clients that send stream_options:{include_usage:true} regardless of stream (e.g. the OpenAI Python SDK) had it passed through on non-streaming calls; NVIDIA NIM rejected it with 400 'Stream options can only be defined when stream=True'. DefaultExecutor.transformRequest only injected/cleared stream_options on the streaming branch and never stripped a client-sent value when stream=false. Add a !stream strip branch; the streaming injection path is unchanged. Global to openai-compat providers.

* fix(qwen-web): cookie validation false-positive - check response body for user object (diegosouzapw#3958)

Integrated into release/v3.8.27

* fix(db): persist backup retention days (diegosouzapw#3970)

Integrated into release/v3.8.27

* 大量UI显示和i18n优化 (diegosouzapw#3973)

Integrated into release/v3.8.27

* deps: bump the npm_and_yarn group across 1 directory with 2 updates (diegosouzapw#3943)

Integrated into release/v3.8.27

* deps: bump form-data from 4.0.5 to 4.0.6 (diegosouzapw#3944)

Integrated into release/v3.8.27

* deps: bump vite from 8.0.5 to 8.0.16 (diegosouzapw#3942)

Integrated into release/v3.8.27

* chore(quality): re-baseline validation.ts 4407->4428 (diegosouzapw#3958 qwen body-check)

The qwen-web validation body-check merged in diegosouzapw#3958 pushed validation.ts past its
frozen size on the integrated release tip. Bump the baseline with justification;
no logic is separately extractable from the existing qwen-web validation branch.

* deps: bump the production group with 13 updates (diegosouzapw#3915)

Integrated into release/v3.8.27 — low-risk group (playwright 1.60→1.61 minor + transitive patches; fumadocs-core 16.9→16.10 minor).

* chore(deps): ignore jscpd major bumps (v5 Rust rewrite breaks the duplication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from diegosouzapw#3916.

* fix(perplexity-web): parse schematized diff_block stream so answers aren't empty (diegosouzapw#4001)

Integrated into release/v3.8.27 — schematized diff_block parsing follow-up to diegosouzapw#3938.

* refactor: modularize providerRegistry.ts into 159 individual provider plugins (diegosouzapw#3993)

Modularize provider registry (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase + behavior-preservation verification (provider-consistency gate 159/232/0, typecheck, registry tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(registry): restore byteplus + mimocode dropped by diegosouzapw#3993 modularization

The provider-registry modularization (diegosouzapw#3993) was cut from a base predating the
byteplus (diegosouzapw#3877) and mimocode (diegosouzapw#3837) registry entries, so merging it silently
dropped both providers (getRegistryEntry returned undefined → validation reported
'not supported'). Re-add them as registry modules in the new structure; registered
count 159→161, provider-consistency 161/232/0.

Also align the pre-existing qwen-web validator test to diegosouzapw#3958: since the validator
now requires a real `user` object in the 200 body, the mock must carry one.

* refactor: modularize schemas (non-stacked) (diegosouzapw#3988)

Modularize validation schemas (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase (reconciled the merged hiddenSidebarGroupLabels diegosouzapw#3971 + intelligenceSyncRequestSchema into the new modules) + behavior verification (typecheck, 195 schema/settings/validation tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(default-executor): honor custom providerSpecificData.baseUrl for OpenAI-format providers (diegosouzapw#4002)

Integrated into release/v3.8.27 — honor custom providerSpecificData.baseUrl in DefaultExecutor (openai-format), tested.

* feat(openai): honor custom base URL in model discovery + complete openai/codex pricing (diegosouzapw#4005)

Integrated into release/v3.8.27 — openai model-discovery honors custom base URL (SSRF-guarded) + pricing rows for new openai/codex models. Tested + baselines bumped.

* fix(live-ws): bridge sidecar events to dashboard (diegosouzapw#4004)

Integrated into release/v3.8.27 — repair LiveWS sidecar (startup, same-origin /live-ws, main→sidecar compression.completed bridge, early-msg queue). Fixed the cookie-parse regex (\s) + added a focused unit test; baseline bumped for the non-blocking chatCore bridge.

* docs(troubleshooting): note MITM proxy cannot intercept Windows-host apps under WSL (diegosouzapw#4003)

Integrated into release/v3.8.27 — MITM/WSL troubleshooting note.

* fix(repo): untrack accidentally-committed root node_modules symlink + gitignore it

A worktree node_modules symlink (-> the main checkout's node_modules) was staged by a
`git add -A` during the diegosouzapw#3988 merge and committed into 05213ac. The symlink points
at the repo's own node_modules path, so checking it out turns the main checkout's
node_modules into a self-referential symlink (breaking tsx/all node ops). Untrack it and
add a root-anchored /node_modules ignore so the symlink form can't be re-committed (the
existing 'node_modules/' only matches directories).

* fix(quality): allowlist socks dep (declared by diegosouzapw#4004, never allowlisted)

socks@^2.8.7 was added to package.json in diegosouzapw#4004 (LiveWS sidecar, 0230213)
as a phantom-dep cleanup but never added to dependency-allowlist.json, so
check:deps has been red on the release tip ever since. socks is the standard
SOCKS proxy client (dep of fetch-socks), legitimate and years old.

* feat(sse): real LLMLingua-2 ONNX compression engine (stable) (diegosouzapw#4014)

Integrated into release/v3.8.27.

Adjustments before merge:
- Synced with the current release tip (was 11 commits behind).
- Added the 3 LLMLingua-2 ONNX optional-runtime deps to dependency-allowlist.json
  (@atjsh/llmlingua-2, @tensorflow/tfjs, js-tiktoken) — the only gate that was red.
- socks was allowlisted directly on release (separate fix d7db5c7; it was declared
  by diegosouzapw#4004 but never allowlisted, leaving check:deps red release-wide).

Verified locally: check:deps OK, file-size OK, public-creds OK, provider-consistency
161/232/0, typecheck:core clean, 24/24 LLMLingua tests pass. The only remaining Fast-QG
red is the pre-existing diegosouzapw#3972 orphan test (request-logger-autorefresh-visibility-3972.test.tsx),
which is release-wide and unrelated to this PR.

* test(dashboard): rehome diegosouzapw#3972 logs auto-refresh test so a runner collects it

tests/unit/request-logger-autorefresh-visibility-3972.test.tsx (added by diegosouzapw#3972
via diegosouzapw#3997) sat at the top level of tests/unit/ as a .tsx vitest test, which NO
runner collects: the node runner only globs *.test.ts, and test:vitest:ui only
runs tests/unit/ui. So the diegosouzapw#3972 regression guard never executed in CI and
check:test-discovery was red release-wide. Move it under tests/unit/ui/ (the
collected vitest:ui path) and fix the relative import depth. Verified: the test
now runs and passes (2/2), and check:test-discovery is green.

* feat(compression): capture per-engine analytics (diegosouzapw#3960) + Lite schema fix (diegosouzapw#3952) (diegosouzapw#4018)

Captures the net-new value from diegosouzapw#3960 (per-engine breakdown analytics) and diegosouzapw#3952 (Lite engine schema fix) onto release/v3.8.27. Fast QG green; 622/622 compression+analytics tests pass.

* fix(sse): guard model-less registry entries in getUnsupportedParams (mimocode) (diegosouzapw#4015)

Real bugfix: guard model-less registry entries (mimocode) in getUnsupportedParams so handleChatCore no longer throws 'entry.models is not iterable' / reports 'All models failed' for unrelated requests. Includes a regression test. Fast QG green.

* feat(ci): Quality Gate v2 — Onda 0 + Onda 1 (gate flips, TIA, SAST, DAST-smoke, mutation infra) (diegosouzapw#4016)

* docs(ops): add quality-gate assessment + replication playbook (Fase 9 foundation)

* feat(ci): flip oasdiff breaking-change gate to blocking (ratchet)

* docs(ops): deliver main branch-protection ruleset for owner to apply

* fix(ci): run typecheck:core in PR->release fast-gates (close fast-gates hole, part 1)

* perf(mutation): enable Stryker incremental mode + cache (scales the 60/80 rollout)

* feat(ci): commit CodeQL advanced config (security-extended), replacing default-setup

* feat(ci): version semgrep SAST workflow (owasp/secrets), advisory

* feat(quality): TIA test-impact map builder (import-graph; map built at runtime, gitignored)

* feat(quality): TIA impacted-test selector with run-all fail-safe

* fix(ci): run TIA-impacted unit tests in PR->release fast-gates (build map at runtime, fail-safe full)

* feat(ci): DAST-smoke per-PR (schemathesis subset + promptfoo injection-guard, blocking)

* fix(ci): unbreak Fase 9 PR CI (MDX frontmatter, CodeQL conflict, dast-smoke advisory)

- Add MDX frontmatter to docs/ops/{BRANCH_PROTECTION_MAIN,QUALITY_GATE_PLAYBOOK}.md.
  fumadocs rejects frontmatter-less docs -> 'npm run build' failed -> broke dast-smoke's
  build step (the release fast-gates never runs build, so this only surfaced on the PR).
- codeql.yml: workflow_dispatch-only until the owner switches repo CodeQL Default->Advanced
  (advanced configs cannot be processed while default setup is enabled; documented inline).
- dast-smoke.yml: job-level continue-on-error (advisory) so this brand-new gate matures
  before it blocks (repo convention: advisory -> blocking).

* ci(quality): make TIA unit-test step advisory until release test-debt is cleared

release/v3.8.27 carries ~17 pre-existing failing unit tests (budget diegosouzapw#3537, apiKey
diegosouzapw#3552, several Zod schemas, Puter/Qwen executors, mimocode entry, etc.) unrelated to
this PR — the new 'run tests on PR->release' gate surfaced them. Per the repo's
advisory->blocking convention, this step enters advisory (it still runs + reports)
so pre-existing debt doesn't block the gate program. typecheck:core stays blocking.
Flip to blocking (remove continue-on-error) once the release suite is green.

* fix(sse): preserve Kiro streaming finish_reason tool_calls (diegosouzapw#3980) (diegosouzapw#4025)

* fix(guardrails): preserve original image when vision-bridge describe fails (diegosouzapw#4012) (diegosouzapw#4026)

* feat(api): advertise combo capabilities on import surfaces (diegosouzapw#3979) (diegosouzapw#4027)

* feat(sse): delegated Anthropic Context Editing for Claude (clear_tool_uses) (diegosouzapw#4021)

Opt-in Claude-only delegated compression: injects context_management.clear_tool_uses_20250919 at the Claude pre-serialization chokepoint (composes with clear_thinking, thinking first), threaded via ExecuteInput from handleChatCore. Pure edit-builder + 11 tests (7 unit + 4 e2e fetch-capture). Beta context-management-2025-06-27 already advertised; allowlist done. Telemetry/400-fallback/claude-web coverage deferred.

* fix(opencode): map x-session-affinity to x-opencode-session for custom providers (diegosouzapw#4022) (diegosouzapw#4028)

* fix(dashboard): Playground Compare tab loading + HTTP method guard (diegosouzapw#4024)

randomUUID non-HTTPS fallback + static CompareTab import; raw HTTP TRACE->405 method guard wired into dev + standalone servers. Integrated into release/v3.8.27.

* refactor(dashboard): settings UI layout + API Keys naming (diegosouzapw#4020)

Presentation/relabel refactor of the Settings dashboard (API Manager -> API Keys), card relocations, Toggle adoption, present-but-disabled engine steps. Auth-file changes are string/comment-only (no behavior change). Integrated into release/v3.8.27.

* fix: restore unit regressions dropped by lossy schema/registry modularizations (diegosouzapw#4030)

Restores schema fields (combo reasoningTokenBuffer, budget-0 diegosouzapw#3537, openrouter preset, proxy family diegosouzapw#3777, resilience degradation/providerCooldown), qwen-web v2 endpoint+catalog, mimocode models key — all dropped by diegosouzapw#3988/diegosouzapw#3993 — and aligns 3 tests to diegosouzapw#3941/diegosouzapw#3993. Verified: 8 failing regression tests on release tip -> 131/131 green on this branch. Integrated into release/v3.8.27.

* fix(api): return 400 (not 500) for malformed JSON on /api/auth/login (diegosouzapw#4031)

Wrap request.json() so a malformed/non-JSON login body returns a structured 400 instead of falling through to the 500 catch. Fixes the schemathesis high-risk-endpoint DAST finding (verified: schemathesis step now passes). +TDD test. Integrated into release/v3.8.27.

* feat(dashboard): real circuit-breaker state in the Combo Live cascade (U1b) (diegosouzapw#4029)

Overlays real provider circuit-breaker state (GET /api/monitoring/health) onto the Combo Live cascade as a 'CB: OPEN · 41s' badge. Pure enrichRunWithBreakers + fail-soft useProviderBreakerHealth poll; graceful when health is absent. +13 tests. Integrated into release/v3.8.27.

* Fix promptfoo security assertion parsing (diegosouzapw#4032)

* chore(deps): dependabot security bumps + drop unused gray-matter (diegosouzapw#4036)

Integrated into release/v3.8.27 — dependabot security bumps (form-data/js-yaml/protobufjs/dompurify/hono) + drop unused gray-matter. Unblocks the npm audit:deps gate (Lint) branch-wide.

* fix(ci): scope TIA to node:test unit files only (mirror test:unit glob) (diegosouzapw#4035)

Integrated into release/v3.8.27 — scopes the advisory TIA step to the test:unit node:test glob, fixing the 99 false failures. +4 TDD.

* Refine compression settings, storage labels, and sidebar grouping (diegosouzapw#4033)

Integrated into release/v3.8.27 — relocate Token Saver into Compression Settings (controlled component), reorder Security/Authz tabs, storage labels + i18n relabel. Thanks @rdself!

* [codex] add per-key local usage command (diegosouzapw#4034)

Integrated into release/v3.8.27 — per-key local @@om-usage command (cached quota, no upstream routing). Rebased onto modularized schemas/keys.ts + file-size rebaseline. Thanks @Witroch4!

* chore(release): reconcile v3.8.27 CHANGELOG + i18n mirrors

* ci(quality): unblock v3.8.27 release gates (zizmor pin + test-masking allowlist)

- zizmor ratchet (151→139, no regression): SHA-pin every action ref ADDED this
  cycle — codeql/dast-smoke/semgrep (3 new workflows) + trivy-action (docker-publish)
  + actions/cache (nightly-mutation). Pre-existing tag refs keep the repo convention.
- test-masking: add config/quality/test-masking-allowlist.json + allowlist support in
  check-test-masking.mjs (exempts ONLY the net-assert-reduction signal; tautology/skip/
  deletion still fire). Allowlists 2 verified-legitimate reductions:
  appearance-widget-settings-schema (diegosouzapw#4033 removed showTokenSaverOnEndpoint field) and
  dashboard-shell-tabs (diegosouzapw#3973 tabs→redirect refactor, asserts replaced). +4 gate tests.

* test(quality): reword test-masking self-test comments to avoid literal masking patterns

The added allowlist-test comments contained the literal strings 'assert.ok(true)' and
'.skip' which the masking detector's own regexes match as text — making the gate flag
its own test file (net +1 tautology/skip/extended-tautology vs main). Reworded to plain
prose ('a new tautology', 'a new skip marker'); test logic unchanged (24/24 pass).

* fix(quality): unblock v3.8.27 release — align 3 stale tests + restore modularized settings-schema parity

Release-PR full CI surfaced 3 deterministic test failures (no live product regression),
all stale vs legitimate cycle changes:

- settings-schema parity (diegosouzapw#3988): the modularized updateSettingsSchema barrel
  (schemas/settings.ts) had diverged from the canonical settingsSchemas.ts (45 vs 85
  fields — 40 dropped + 6 extra), a lossy-modularization dead-code copy. Re-export from
  the canonical source so the barrel can never diverge again (runtime already uses
  canonical). Parity test now passes.
- api-manager permissions modal: diegosouzapw#4034 added a 4th self-service switch (per-key usage
  allowance); a11y invariant (every switch type="button") still holds. Updated the
  static count 3 -> 4.
- pack-artifact policy: dist/http-method-guard.cjs became a required runtime path;
  added it to the test's expected missing-paths list.

Also documents the gate gap for Fase 9 (QUALITY_GATE_PLAYBOOK Parte 6): G1 run the
deterministic unit layer + test-masking on PR->release (not just PR->main), G2 a
modularization-parity gate (would have caught the diegosouzapw#3988 drop at its PR), G3 flake
quarantine. Env flakes (LiveWS startup timeout, integration server-startup cascade)
are pre-existing/CI-env, triaged separately.

---------

Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Veier04 <118300867+Veier04@users.noreply.github.com>
Co-authored-by: Felipe Sartori <felipesartori.ti@gmail.com>
Co-authored-by: WormAlien <164898390+WormAlien@users.noreply.github.com>
Co-authored-by: thezukiru <121331256+thezukiru@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Demiurge The Single <megamen932@gmail.com>
Co-authored-by: Witroch4 <witalo_rocha@hotmail.com>
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…lication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from diegosouzapw#3916.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
* chore(release): open v3.8.27 development cycle

* fix(security): polynomial ReDoS in comboAgentMiddleware regex (diegosouzapw#3982)

* fix(security): eliminate polynomial ReDoS in comboAgentMiddleware <omniModel> regex (CodeQL js/polynomial-redos)

CACHE_TAG_PATTERN wrapped the tag in an unbounded `(?:\\n|\n|\r)*` prefix/suffix.
On an unanchored `.test()`/`.exec()` that is O(n²) on inputs with many newlines
(CodeQL js/polynomial-redos, alerts diegosouzapw#612/diegosouzapw#613). The surrounding runs are irrelevant
to detecting/capturing the tag, so the detection pattern now matches only the core
`<omniModel>([^<]+)</omniModel>`; the global strip pattern still consumes the
wrapping newlines (combo.ts streaming, diegosouzapw#531) but BOUNDED ({0,16}) so it stays linear.

Behavior preserved: detection, model extraction, multi-tag stripping (diegosouzapw#454) and
blank-line cleanup all unchanged (107 related tests green). Adds ReDoS-safety
regression tests (50k-newline inputs complete in <1ms).

* docs(changelog): add diegosouzapw#3982 ReDoS fix to [3.8.27]

* ci(security): harden workflows — artipacked persist-credentials + cache-poisoning + SC2086 (diegosouzapw#3965)

* Refine provider quota card display (diegosouzapw#3969)

Integrated into release/v3.8.27

* feat: add sidebar group separator toggles (diegosouzapw#3971)

Integrated into release/v3.8.27

* Gate control-plane proxy direct fallback (diegosouzapw#3963)

Integrated into release/v3.8.27

* Capture actual upstream provider requests (diegosouzapw#3941)

Integrated into release/v3.8.27

* ci(quality): flip require-tighten + osv + Trivy to blocking (v3.8.27 cycle-end) (diegosouzapw#3984)

* fix(resilience): respect connection cooldown stored as numeric epoch (diegosouzapw#3954) (diegosouzapw#3995)

rate_limited_until is a TEXT column, but setConnectionRateLimitUntil (Antigravity full-quota path) persists a raw epoch number that SQLite coerces to a numeric string ("1781696905131.0"). The selection predicate isAccountUnavailable then did new Date("1781696905131.0") -> NaN, so the cooling connection was never skipped and the router kept dispatching to rate-limited accounts. Normalize numeric-epoch strings (and number/Date/ISO) via a shared cooldownUntilMs() helper in isAccountUnavailable / getEarliestRateLimitedUntil / filterAvailableAccounts / parseFutureDateMs. ISO behavior preserved.

* fix(providers): fetch live /models for LLM7 and BytePlus (diegosouzapw#3976) (diegosouzapw#3996)

llm7 and byteplus carry a real modelsUrl but were not classified by any live-fetch branch of the model-import route, so their hardcoded 4-entry registry catalog was served (source local_catalog) instead of the upstream catalog. Add both to NAMED_OPENAI_STYLE_PROVIDERS so the route probes <baseUrl>/models and serves the live list, falling back to the local catalog only on fetch failure.

* fix(dashboard): logs auto-refresh reads live visibility, not a stale mount ref (diegosouzapw#3972) (diegosouzapw#3997)

The auto-refresh interval gated each tick on visibleRef, seeded once at mount and updated only by a visibilitychange event. A tab mounted while document.visibilityState is 'hidden' (background load, bfcache, embedded/proxied webviews) with no later visibilitychange left the ref false forever, so the interval ticked but never fetched — only the manual button worked. Read the live document.visibilityState in the tick instead.

* feat(compression): add Indonesian caveman rules and language pack (diegosouzapw#3975)

Integrated into release/v3.8.27

(cherry picked from commit 272240a)

* fix(combo): shuffle strict-random fallback remainder to spread load (diegosouzapw#3959) (diegosouzapw#3998)

strict-random shuffled only the deck-selected slot 0 and left the fallback remainder in fixed priority order, so after a failing deck pick the chain always fell through to the same top-priority model — a persistently-failing model was retried on essentially every request and fallback load never spread across peers. Shuffle the remainder too (like the random strategy).

* Add provider auth visibility controls (diegosouzapw#3953)

Integrated into release/v3.8.27

* fix(claude): forward client tool-search-tool anthropic-beta on the Claude OAuth path (diegosouzapw#3974) (diegosouzapw#3999)

The client-negotiated anthropic-beta: tool-search-tool-2025-10-19 was dropped on both Claude code paths (default executor rebuilt from static ANTHROPIC_BETA_CLAUDE_OAUTH; selectBetaFlags only read the client beta to gate thinking/effort), so claude.ai rejected deferred-tool requests with 400 'Tool reference not found'. Add an allowlist-merge (mergeClientAnthropicBeta) that unions the client's allowlisted betas into the outbound set on both paths, preserving diegosouzapw#3415 (no forced thinking/effort).

* feat(providers): add model search filter to provider dashboard (diegosouzapw#3950)

Integrated into release/v3.8.27

* fix(vision-bridge): force bridge for tokenrouter deepseek models (diegosouzapw#3946)

Integrated into release/v3.8.27

* fix(executor): strip stream_options on non-streaming requests (diegosouzapw#3884) (diegosouzapw#4000)

Clients that send stream_options:{include_usage:true} regardless of stream (e.g. the OpenAI Python SDK) had it passed through on non-streaming calls; NVIDIA NIM rejected it with 400 'Stream options can only be defined when stream=True'. DefaultExecutor.transformRequest only injected/cleared stream_options on the streaming branch and never stripped a client-sent value when stream=false. Add a !stream strip branch; the streaming injection path is unchanged. Global to openai-compat providers.

* fix(qwen-web): cookie validation false-positive - check response body for user object (diegosouzapw#3958)

Integrated into release/v3.8.27

* fix(db): persist backup retention days (diegosouzapw#3970)

Integrated into release/v3.8.27

* 大量UI显示和i18n优化 (diegosouzapw#3973)

Integrated into release/v3.8.27

* deps: bump the npm_and_yarn group across 1 directory with 2 updates (diegosouzapw#3943)

Integrated into release/v3.8.27

* deps: bump form-data from 4.0.5 to 4.0.6 (diegosouzapw#3944)

Integrated into release/v3.8.27

* deps: bump vite from 8.0.5 to 8.0.16 (diegosouzapw#3942)

Integrated into release/v3.8.27

* chore(quality): re-baseline validation.ts 4407->4428 (diegosouzapw#3958 qwen body-check)

The qwen-web validation body-check merged in diegosouzapw#3958 pushed validation.ts past its
frozen size on the integrated release tip. Bump the baseline with justification;
no logic is separately extractable from the existing qwen-web validation branch.

* deps: bump the production group with 13 updates (diegosouzapw#3915)

Integrated into release/v3.8.27 — low-risk group (playwright 1.60→1.61 minor + transitive patches; fumadocs-core 16.9→16.10 minor).

* chore(deps): ignore jscpd major bumps (v5 Rust rewrite breaks the duplication gate)

Our duplication ratchet (scripts/check/check-duplication.mjs) is pinned to jscpd@4
and parses jscpd-report.json against a frozen baseline. jscpd v5 is a native Rust
binary with no Node.js API and a different report/bin, so a major bump would break
the gate. Migrate deliberately, not via dependabot. Closes the noise from diegosouzapw#3916.

* fix(perplexity-web): parse schematized diff_block stream so answers aren't empty (diegosouzapw#4001)

Integrated into release/v3.8.27 — schematized diff_block parsing follow-up to diegosouzapw#3938.

* refactor: modularize providerRegistry.ts into 159 individual provider plugins (diegosouzapw#3993)

Modularize provider registry (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase + behavior-preservation verification (provider-consistency gate 159/232/0, typecheck, registry tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(registry): restore byteplus + mimocode dropped by diegosouzapw#3993 modularization

The provider-registry modularization (diegosouzapw#3993) was cut from a base predating the
byteplus (diegosouzapw#3877) and mimocode (diegosouzapw#3837) registry entries, so merging it silently
dropped both providers (getRegistryEntry returned undefined → validation reported
'not supported'). Re-add them as registry modules in the new structure; registered
count 159→161, provider-consistency 161/232/0.

Also align the pre-existing qwen-web validator test to diegosouzapw#3958: since the validator
now requires a real `user` object in the 200 body, the mock must carry one.

* refactor: modularize schemas (non-stacked) (diegosouzapw#3988)

Modularize validation schemas (diegosouzapw#3594). Integrated into release/v3.8.27 after rebase (reconciled the merged hiddenSidebarGroupLabels diegosouzapw#3971 + intelligenceSyncRequestSchema into the new modules) + behavior verification (typecheck, 195 schema/settings/validation tests, build 556/556).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(default-executor): honor custom providerSpecificData.baseUrl for OpenAI-format providers (diegosouzapw#4002)

Integrated into release/v3.8.27 — honor custom providerSpecificData.baseUrl in DefaultExecutor (openai-format), tested.

* feat(openai): honor custom base URL in model discovery + complete openai/codex pricing (diegosouzapw#4005)

Integrated into release/v3.8.27 — openai model-discovery honors custom base URL (SSRF-guarded) + pricing rows for new openai/codex models. Tested + baselines bumped.

* fix(live-ws): bridge sidecar events to dashboard (diegosouzapw#4004)

Integrated into release/v3.8.27 — repair LiveWS sidecar (startup, same-origin /live-ws, main→sidecar compression.completed bridge, early-msg queue). Fixed the cookie-parse regex (\s) + added a focused unit test; baseline bumped for the non-blocking chatCore bridge.

* docs(troubleshooting): note MITM proxy cannot intercept Windows-host apps under WSL (diegosouzapw#4003)

Integrated into release/v3.8.27 — MITM/WSL troubleshooting note.

* fix(repo): untrack accidentally-committed root node_modules symlink + gitignore it

A worktree node_modules symlink (-> the main checkout's node_modules) was staged by a
`git add -A` during the diegosouzapw#3988 merge and committed into f5f430daa. The symlink points
at the repo's own node_modules path, so checking it out turns the main checkout's
node_modules into a self-referential symlink (breaking tsx/all node ops). Untrack it and
add a root-anchored /node_modules ignore so the symlink form can't be re-committed (the
existing 'node_modules/' only matches directories).

* fix(quality): allowlist socks dep (declared by diegosouzapw#4004, never allowlisted)

socks@^2.8.7 was added to package.json in diegosouzapw#4004 (LiveWS sidecar, 4551e22ca)
as a phantom-dep cleanup but never added to dependency-allowlist.json, so
check:deps has been red on the release tip ever since. socks is the standard
SOCKS proxy client (dep of fetch-socks), legitimate and years old.

* feat(sse): real LLMLingua-2 ONNX compression engine (stable) (diegosouzapw#4014)

Integrated into release/v3.8.27.

Adjustments before merge:
- Synced with the current release tip (was 11 commits behind).
- Added the 3 LLMLingua-2 ONNX optional-runtime deps to dependency-allowlist.json
  (@atjsh/llmlingua-2, @tensorflow/tfjs, js-tiktoken) — the only gate that was red.
- socks was allowlisted directly on release (separate fix eafbc56c9; it was declared
  by diegosouzapw#4004 but never allowlisted, leaving check:deps red release-wide).

Verified locally: check:deps OK, file-size OK, public-creds OK, provider-consistency
161/232/0, typecheck:core clean, 24/24 LLMLingua tests pass. The only remaining Fast-QG
red is the pre-existing diegosouzapw#3972 orphan test (request-logger-autorefresh-visibility-3972.test.tsx),
which is release-wide and unrelated to this PR.

* test(dashboard): rehome diegosouzapw#3972 logs auto-refresh test so a runner collects it

tests/unit/request-logger-autorefresh-visibility-3972.test.tsx (added by diegosouzapw#3972
via diegosouzapw#3997) sat at the top level of tests/unit/ as a .tsx vitest test, which NO
runner collects: the node runner only globs *.test.ts, and test:vitest:ui only
runs tests/unit/ui. So the diegosouzapw#3972 regression guard never executed in CI and
check:test-discovery was red release-wide. Move it under tests/unit/ui/ (the
collected vitest:ui path) and fix the relative import depth. Verified: the test
now runs and passes (2/2), and check:test-discovery is green.

* feat(compression): capture per-engine analytics (diegosouzapw#3960) + Lite schema fix (diegosouzapw#3952) (diegosouzapw#4018)

Captures the net-new value from diegosouzapw#3960 (per-engine breakdown analytics) and diegosouzapw#3952 (Lite engine schema fix) onto release/v3.8.27. Fast QG green; 622/622 compression+analytics tests pass.

* fix(sse): guard model-less registry entries in getUnsupportedParams (mimocode) (diegosouzapw#4015)

Real bugfix: guard model-less registry entries (mimocode) in getUnsupportedParams so handleChatCore no longer throws 'entry.models is not iterable' / reports 'All models failed' for unrelated requests. Includes a regression test. Fast QG green.

* feat(ci): Quality Gate v2 — Onda 0 + Onda 1 (gate flips, TIA, SAST, DAST-smoke, mutation infra) (diegosouzapw#4016)

* docs(ops): add quality-gate assessment + replication playbook (Fase 9 foundation)

* feat(ci): flip oasdiff breaking-change gate to blocking (ratchet)

* docs(ops): deliver main branch-protection ruleset for owner to apply

* fix(ci): run typecheck:core in PR->release fast-gates (close fast-gates hole, part 1)

* perf(mutation): enable Stryker incremental mode + cache (scales the 60/80 rollout)

* feat(ci): commit CodeQL advanced config (security-extended), replacing default-setup

* feat(ci): version semgrep SAST workflow (owasp/secrets), advisory

* feat(quality): TIA test-impact map builder (import-graph; map built at runtime, gitignored)

* feat(quality): TIA impacted-test selector with run-all fail-safe

* fix(ci): run TIA-impacted unit tests in PR->release fast-gates (build map at runtime, fail-safe full)

* feat(ci): DAST-smoke per-PR (schemathesis subset + promptfoo injection-guard, blocking)

* fix(ci): unbreak Fase 9 PR CI (MDX frontmatter, CodeQL conflict, dast-smoke advisory)

- Add MDX frontmatter to docs/ops/{BRANCH_PROTECTION_MAIN,QUALITY_GATE_PLAYBOOK}.md.
  fumadocs rejects frontmatter-less docs -> 'npm run build' failed -> broke dast-smoke's
  build step (the release fast-gates never runs build, so this only surfaced on the PR).
- codeql.yml: workflow_dispatch-only until the owner switches repo CodeQL Default->Advanced
  (advanced configs cannot be processed while default setup is enabled; documented inline).
- dast-smoke.yml: job-level continue-on-error (advisory) so this brand-new gate matures
  before it blocks (repo convention: advisory -> blocking).

* ci(quality): make TIA unit-test step advisory until release test-debt is cleared

release/v3.8.27 carries ~17 pre-existing failing unit tests (budget diegosouzapw#3537, apiKey
diegosouzapw#3552, several Zod schemas, Puter/Qwen executors, mimocode entry, etc.) unrelated to
this PR — the new 'run tests on PR->release' gate surfaced them. Per the repo's
advisory->blocking convention, this step enters advisory (it still runs + reports)
so pre-existing debt doesn't block the gate program. typecheck:core stays blocking.
Flip to blocking (remove continue-on-error) once the release suite is green.

* fix(sse): preserve Kiro streaming finish_reason tool_calls (diegosouzapw#3980) (diegosouzapw#4025)

* fix(guardrails): preserve original image when vision-bridge describe fails (diegosouzapw#4012) (diegosouzapw#4026)

* feat(api): advertise combo capabilities on import surfaces (diegosouzapw#3979) (diegosouzapw#4027)

* feat(sse): delegated Anthropic Context Editing for Claude (clear_tool_uses) (diegosouzapw#4021)

Opt-in Claude-only delegated compression: injects context_management.clear_tool_uses_20250919 at the Claude pre-serialization chokepoint (composes with clear_thinking, thinking first), threaded via ExecuteInput from handleChatCore. Pure edit-builder + 11 tests (7 unit + 4 e2e fetch-capture). Beta context-management-2025-06-27 already advertised; allowlist done. Telemetry/400-fallback/claude-web coverage deferred.

* fix(opencode): map x-session-affinity to x-opencode-session for custom providers (diegosouzapw#4022) (diegosouzapw#4028)

* fix(dashboard): Playground Compare tab loading + HTTP method guard (diegosouzapw#4024)

randomUUID non-HTTPS fallback + static CompareTab import; raw HTTP TRACE->405 method guard wired into dev + standalone servers. Integrated into release/v3.8.27.

* refactor(dashboard): settings UI layout + API Keys naming (diegosouzapw#4020)

Presentation/relabel refactor of the Settings dashboard (API Manager -> API Keys), card relocations, Toggle adoption, present-but-disabled engine steps. Auth-file changes are string/comment-only (no behavior change). Integrated into release/v3.8.27.

* fix: restore unit regressions dropped by lossy schema/registry modularizations (diegosouzapw#4030)

Restores schema fields (combo reasoningTokenBuffer, budget-0 diegosouzapw#3537, openrouter preset, proxy family diegosouzapw#3777, resilience degradation/providerCooldown), qwen-web v2 endpoint+catalog, mimocode models key — all dropped by diegosouzapw#3988/diegosouzapw#3993 — and aligns 3 tests to diegosouzapw#3941/diegosouzapw#3993. Verified: 8 failing regression tests on release tip -> 131/131 green on this branch. Integrated into release/v3.8.27.

* fix(api): return 400 (not 500) for malformed JSON on /api/auth/login (diegosouzapw#4031)

Wrap request.json() so a malformed/non-JSON login body returns a structured 400 instead of falling through to the 500 catch. Fixes the schemathesis high-risk-endpoint DAST finding (verified: schemathesis step now passes). +TDD test. Integrated into release/v3.8.27.

* feat(dashboard): real circuit-breaker state in the Combo Live cascade (U1b) (diegosouzapw#4029)

Overlays real provider circuit-breaker state (GET /api/monitoring/health) onto the Combo Live cascade as a 'CB: OPEN · 41s' badge. Pure enrichRunWithBreakers + fail-soft useProviderBreakerHealth poll; graceful when health is absent. +13 tests. Integrated into release/v3.8.27.

* Fix promptfoo security assertion parsing (diegosouzapw#4032)

* chore(deps): dependabot security bumps + drop unused gray-matter (diegosouzapw#4036)

Integrated into release/v3.8.27 — dependabot security bumps (form-data/js-yaml/protobufjs/dompurify/hono) + drop unused gray-matter. Unblocks the npm audit:deps gate (Lint) branch-wide.

* fix(ci): scope TIA to node:test unit files only (mirror test:unit glob) (diegosouzapw#4035)

Integrated into release/v3.8.27 — scopes the advisory TIA step to the test:unit node:test glob, fixing the 99 false failures. +4 TDD.

* Refine compression settings, storage labels, and sidebar grouping (diegosouzapw#4033)

Integrated into release/v3.8.27 — relocate Token Saver into Compression Settings (controlled component), reorder Security/Authz tabs, storage labels + i18n relabel. Thanks @rdself!

* [codex] add per-key local usage command (diegosouzapw#4034)

Integrated into release/v3.8.27 — per-key local @@om-usage command (cached quota, no upstream routing). Rebased onto modularized schemas/keys.ts + file-size rebaseline. Thanks @Witroch4!

* chore(release): reconcile v3.8.27 CHANGELOG + i18n mirrors

* ci(quality): unblock v3.8.27 release gates (zizmor pin + test-masking allowlist)

- zizmor ratchet (151→139, no regression): SHA-pin every action ref ADDED this
  cycle — codeql/dast-smoke/semgrep (3 new workflows) + trivy-action (docker-publish)
  + actions/cache (nightly-mutation). Pre-existing tag refs keep the repo convention.
- test-masking: add config/quality/test-masking-allowlist.json + allowlist support in
  check-test-masking.mjs (exempts ONLY the net-assert-reduction signal; tautology/skip/
  deletion still fire). Allowlists 2 verified-legitimate reductions:
  appearance-widget-settings-schema (diegosouzapw#4033 removed showTokenSaverOnEndpoint field) and
  dashboard-shell-tabs (diegosouzapw#3973 tabs→redirect refactor, asserts replaced). +4 gate tests.

* test(quality): reword test-masking self-test comments to avoid literal masking patterns

The added allowlist-test comments contained the literal strings 'assert.ok(true)' and
'.skip' which the masking detector's own regexes match as text — making the gate flag
its own test file (net +1 tautology/skip/extended-tautology vs main). Reworded to plain
prose ('a new tautology', 'a new skip marker'); test logic unchanged (24/24 pass).

* fix(quality): unblock v3.8.27 release — align 3 stale tests + restore modularized settings-schema parity

Release-PR full CI surfaced 3 deterministic test failures (no live product regression),
all stale vs legitimate cycle changes:

- settings-schema parity (diegosouzapw#3988): the modularized updateSettingsSchema barrel
  (schemas/settings.ts) had diverged from the canonical settingsSchemas.ts (45 vs 85
  fields — 40 dropped + 6 extra), a lossy-modularization dead-code copy. Re-export from
  the canonical source so the barrel can never diverge again (runtime already uses
  canonical). Parity test now passes.
- api-manager permissions modal: diegosouzapw#4034 added a 4th self-service switch (per-key usage
  allowance); a11y invariant (every switch type="button") still holds. Updated the
  static count 3 -> 4.
- pack-artifact policy: dist/http-method-guard.cjs became a required runtime path;
  added it to the test's expected missing-paths list.

Also documents the gate gap for Fase 9 (QUALITY_GATE_PLAYBOOK Parte 6): G1 run the
deterministic unit layer + test-masking on PR->release (not just PR->main), G2 a
modularization-parity gate (would have caught the diegosouzapw#3988 drop at its PR), G3 flake
quarantine. Env flakes (LiveWS startup timeout, integration server-startup cascade)
are pre-existing/CI-env, triaged separately.

---------

Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Veier04 <118300867+Veier04@users.noreply.github.com>
Co-authored-by: Felipe Sartori <felipesartori.ti@gmail.com>
Co-authored-by: WormAlien <164898390+WormAlien@users.noreply.github.com>
Co-authored-by: thezukiru <121331256+thezukiru@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: NOXX - Commiter <artur1992123@mail.ru>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Demiurge The Single <megamen932@gmail.com>
Co-authored-by: Witroch4 <witalo_rocha@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant