Compare commits

..
Author SHA1 Message Date
Calibrain 1747b3466e Fix linting issues 2026-07-21 19:52:25 +00:00
CaliBrain 81a057c8a0 Try and fix OIDC (#1127) 2026-07-21 15:43:54 -04:00
Matt Van HornandMatt Van Horn 91b1064689 fix(naming): respect subfolder order when assigning audiobook part numbers (#1123)
## Summary

Audiobooks whose files are split across nested subfolders now keep their
on-disk folder order when "Rename and Organize" assigns part numbers.
Previously `natural_sort_key` keyed on `Path(path).name`, so identically
named files from different folders (`001.mp3` in `00_Introduction/` vs
`06_Side 6/`) collapsed together and the part sequence scrambled.

## Background

zazizou reported in #1007 that the total file count was right but
`06_Side 6/001.mp3` came out as part 1 instead of
`00_Introduction/001_About.mp3`. `scan.py` flattens every nested file
into one list and `assign_part_numbers` sorts it with
`natural_sort_key`, which discarded the parent-folder prefix. The fix
pads the existing `PAD_NUMBERS_PATTERN` numbers over the full relative
path (`str(path).lower()`) rather than the basename, so nested
audiobooks sort by folder first and then by filename. Flat directories
are unaffected because their files share a prefix, and
`natural_sort_key` is only called from `assign_part_numbers`, so nothing
else changes. I updated the test that pinned the old basename-only
ordering and added nested-subfolder and duplicate-basename cases;
`pytest tests/core/test_naming.py
tests/core/test_part_number_extraction.py` passes (102 tests).

Closes #1007

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-07-21 15:41:03 -04:00
dependabot[bot] c9a2b5eccf Bump the python-deps group across 1 directory with 4 updates (#1126)
Bumps the python-deps group with 4 updates in the / directory:
[tqdm](https://github.com/tqdm/tqdm),
[seleniumbase](https://github.com/seleniumbase/SeleniumBase),
[prek](https://github.com/j178/prek) and
[ruff](https://github.com/astral-sh/ruff).

Updates `tqdm` from 4.68.4 to 4.69.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tqdm/tqdm/releases">tqdm's
releases</a>.</em></p>
<blockquote>
<h2>tqdm v4.69.0 stable</h2>
<ul>
<li>add <code>tqdm.asyncio.gather(..., return_exceptions=False)</code>
(<a href="https://redirect.github.com/tqdm/tqdm/issues/1776">#1776</a>,
<a href="https://redirect.github.com/tqdm/tqdm/issues/1671">#1671</a>
&lt;- <a
href="https://redirect.github.com/tqdm/tqdm/issues/1286">#1286</a>)</li>
<li>misc minor framework updates
<ul>
<li>bump workflow actions &amp; pre-commit hooks</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tqdm/tqdm/commit/6ab24dcc5df910044f1f6e0685f95dbf9cd424f3"><code>6ab24dc</code></a>
bump version, workflow actions, pre-commit hooks</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/99615b978702dcf61986de62dfd252d82720af76"><code>99615b9</code></a>
asyncio: add gather(return_exceptions=False) (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1776">#1776</a>)</li>
<li>See full diff in <a
href="https://github.com/tqdm/tqdm/compare/v4.68.4...v4.69.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.51.0 to 4.51.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.51.2 - CDP Mode: Patch 120</h2>
<h2>CDP Mode: Patch 120</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7614ca495d8a52a2100516c0fcad079e191c13f4">Fix
WebRTC leak for non-proxied navigation</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4428">seleniumbase/SeleniumBase#4428</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/92c528ae17d0e07294671d09cb253c5e5ebbb8ca">Drop
support for the deprecated Atlas Browser</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4427">seleniumbase/SeleniumBase#4427</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9c0f401a9977efbb7d13114aaf98a52a0532af9c">Remove
Copilot examples (requires login now)</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4429">seleniumbase/SeleniumBase#4429</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/aca0363058c95c4590ff6639e4e51d05010ddbe8">Add
a CDP Mode fingerprint test</a>
-- (Uses the Clearcote fingerprint scanner / auditor)</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e152f11df548e76ec34822188a5234f6cb09cd57">Update
Stealthy Playwright Mode examples</a>
-- (<code>sb.goto(url)</code> is stealthier than
<code>page.goto(url)</code>)</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/93de30adf71d6b3277512ab78f1ddf1eb0b586d3">Refresh
Python dependencies</a>
-- (<code>filelock</code> and <code>coverage</code>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 120 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4430">seleniumbase/SeleniumBase#4430</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.51.1...v4.51.2">https://github.com/seleniumbase/SeleniumBase/compare/v4.51.1...v4.51.2</a></p>
<h2>4.51.1 - Updates to multiple areas</h2>
<h2>Updates to multiple areas</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/706e23c5b25000e64f9b97dbb9118717eafaed05">Update
the xpath-to-css converter</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1c7fa3bbefd870e79e3b3e75044b2a88258f204e">Update
the CDP Mode ad-block list</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cb6fbb103b4dc61d2f6d425c54dc966b4fd6181e">Update
error messages for proxy failures</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/fe392b5b3fd90a04d0d266ddbcd76cbcc7ccab7c">Update
proxy validation</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/dd14d5e0c7832150d70b6bd3bd950cc3a8ad10cb">Update
the Slider CAPTCHA solver</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/97d53f601faa2f8247eea00271ce6140e3d7d158">Update
CDP Mode examples</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Updates to multiple areas by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4424">seleniumbase/SeleniumBase#4424</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.51.0...v4.51.1">https://github.com/seleniumbase/SeleniumBase/compare/v4.51.0...v4.51.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f9fca2dc604067020363b285b0fff15910e64cea"><code>f9fca2d</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4430">#4430</a>
from seleniumbase/cdp-mode-patch-120</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e4f803f5adc47880c5563c7ae528d1a190249865"><code>e4f803f</code></a>
Version 4.51.2</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/93de30adf71d6b3277512ab78f1ddf1eb0b586d3"><code>93de30a</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e152f11df548e76ec34822188a5234f6cb09cd57"><code>e152f11</code></a>
Update Stealthy Playwright Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/aca0363058c95c4590ff6639e4e51d05010ddbe8"><code>aca0363</code></a>
Add a CDP Mode fingerprint test</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9c0f401a9977efbb7d13114aaf98a52a0532af9c"><code>9c0f401</code></a>
Remove Copilot examples (requires login now)</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/92c528ae17d0e07294671d09cb253c5e5ebbb8ca"><code>92c528a</code></a>
Drop support for the deprecated Atlas Browser</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7614ca495d8a52a2100516c0fcad079e191c13f4"><code>7614ca4</code></a>
Fix WebRTC leak for non-proxied navigation</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/45a338be063e2ae0561779c1ca5433804242d98d"><code>45a338b</code></a>
Update CDP Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a1fd937c94825d1f668eacc457cb9539bfb22d93"><code>a1fd937</code></a>
Update CDP Mode examples</li>
<li>Additional commits viewable in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.51.0...v4.51.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `prek` from 0.4.9 to 0.4.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.10</h2>
<h2>Release Notes</h2>
<p>Released on 2026-07-16.</p>
<h3>Enhancements</h3>
<ul>
<li>Add PHP language support (<a
href="https://redirect.github.com/j178/prek/pull/2314">#2314</a>)</li>
<li>Add freeze option to update settings (<a
href="https://redirect.github.com/j178/prek/pull/2323">#2323</a>)</li>
<li>Add tag filters to update configuration (<a
href="https://redirect.github.com/j178/prek/pull/2354">#2354</a>)</li>
<li>Identify 'mts' and 'cts' as TypeScript files (<a
href="https://redirect.github.com/j178/prek/pull/2209">#2209</a>)</li>
<li>Publish Alpine Docker images (<a
href="https://redirect.github.com/j178/prek/pull/2352">#2352</a>)</li>
<li>Support builtin and meta in try-repo (<a
href="https://redirect.github.com/j178/prek/pull/2350">#2350</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix Python discovery order (<a
href="https://redirect.github.com/j178/prek/pull/2348">#2348</a>)</li>
<li>Fix Windows progress rendering (<a
href="https://redirect.github.com/j178/prek/pull/2328">#2328</a>)</li>
<li>Preserve configured repo values for updates (<a
href="https://redirect.github.com/j178/prek/pull/2324">#2324</a>)</li>
<li>Scope synthetic <code>GIT_WORK_TREE</code> to git commands (<a
href="https://redirect.github.com/j178/prek/pull/2356">#2356</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Expand common workflows guide (<a
href="https://redirect.github.com/j178/prek/pull/2351">#2351</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
<h2>Install prek 0.4.10</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://github.com/j178/prek/releases/download/v0.4.10/prek-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://github.com/j178/prek/releases/download/v0.4.10/prek-installer.ps1
| iex&quot;
</code></pre>
<h3>Install prebuilt binaries via Homebrew</h3>
<pre lang="sh"><code>brew install prek
</code></pre>
<h2>Download prek 0.4.10</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.10</h2>
<p>Released on 2026-07-16.</p>
<h3>Enhancements</h3>
<ul>
<li>Add PHP language support (<a
href="https://redirect.github.com/j178/prek/pull/2314">#2314</a>)</li>
<li>Add freeze option to update settings (<a
href="https://redirect.github.com/j178/prek/pull/2323">#2323</a>)</li>
<li>Add tag filters to update configuration (<a
href="https://redirect.github.com/j178/prek/pull/2354">#2354</a>)</li>
<li>Identify 'mts' and 'cts' as TypeScript files (<a
href="https://redirect.github.com/j178/prek/pull/2209">#2209</a>)</li>
<li>Publish Alpine Docker images (<a
href="https://redirect.github.com/j178/prek/pull/2352">#2352</a>)</li>
<li>Support builtin and meta in try-repo (<a
href="https://redirect.github.com/j178/prek/pull/2350">#2350</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix Python discovery order (<a
href="https://redirect.github.com/j178/prek/pull/2348">#2348</a>)</li>
<li>Fix Windows progress rendering (<a
href="https://redirect.github.com/j178/prek/pull/2328">#2328</a>)</li>
<li>Preserve configured repo values for updates (<a
href="https://redirect.github.com/j178/prek/pull/2324">#2324</a>)</li>
<li>Scope synthetic <code>GIT_WORK_TREE</code> to git commands (<a
href="https://redirect.github.com/j178/prek/pull/2356">#2356</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Expand common workflows guide (<a
href="https://redirect.github.com/j178/prek/pull/2351">#2351</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/b45e6710082ed28943c96268d0ea99026dbb13ba"><code>b45e671</code></a>
Bump version to 0.4.10 (<a
href="https://redirect.github.com/j178/prek/issues/2358">#2358</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/0cf3be5280613835759de9912ec57eb724d3db22"><code>0cf3be5</code></a>
Scope synthetic <code>GIT_WORK_TREE</code> to git commands (<a
href="https://redirect.github.com/j178/prek/issues/2356">#2356</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/0265dddfff97f1be7fcf3aaeefdeeb12572473de"><code>0265ddd</code></a>
Add tag filters to update configuration (<a
href="https://redirect.github.com/j178/prek/issues/2354">#2354</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/dcfa91b31b3b165bee4bc472291aadaf7910069f"><code>dcfa91b</code></a>
Publish Alpine Docker images (<a
href="https://redirect.github.com/j178/prek/issues/2352">#2352</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/1e0b2c108458e781c827695bd075406a13f15cb6"><code>1e0b2c1</code></a>
Expand common workflows guide (<a
href="https://redirect.github.com/j178/prek/issues/2351">#2351</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/753e13c4fe94d83695da6bc16f2939770c9aa219"><code>753e13c</code></a>
Support builtin and meta in try-repo (<a
href="https://redirect.github.com/j178/prek/issues/2350">#2350</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/1e2abfb81f5213990413f222ad4d7444af430518"><code>1e2abfb</code></a>
Fix Python discovery order (<a
href="https://redirect.github.com/j178/prek/issues/2348">#2348</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ec15d683e1b9bd8e265d92d7116bf19b574fedc9"><code>ec15d68</code></a>
Update Rust crate indicatif to v0.18.6 (<a
href="https://redirect.github.com/j178/prek/issues/2330">#2330</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ba4939a4856803ea1c4b886d5c8b3b9ba19df74a"><code>ba4939a</code></a>
Update Rust crate fs-err to v3.3.1 (<a
href="https://redirect.github.com/j178/prek/issues/2329">#2329</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/e43acba74e33728d30277a2c229eaed1def17b49"><code>e43acba</code></a>
Improve contribution templates (<a
href="https://redirect.github.com/j178/prek/issues/2347">#2347</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.4.9...v0.4.10">compare
view</a></li>
</ul>
</details>
<br />

Updates `ruff` from 0.15.21 to 0.15.22
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.22</h2>
<h2>Release Notes</h2>
<p>Released on 2026-07-16.</p>
<h3>Preview features</h3>
<ul>
<li>[<code>pycodestyle</code>] Add an autofix for <code>E402</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22212">#22212</a>)</li>
<li>[<code>refurb</code>] Allow subclassing builtins in stub files
(<code>FURB189</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26812">#26812</a>)</li>
<li>[<code>ruff</code>] Add rule to replace <code>noqa</code> comments
with <code>ruff:ignore</code> (<code>RUF105</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26423">#26423</a>)</li>
<li>[<code>ruff</code>] Add rule to use human-readable names in
<code>ruff:ignore</code> comments (<code>RUF106</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26682">#26682</a>)</li>
<li>[<code>ruff</code>] Add rule to use human-readable names in
configuration selectors (<code>RUF201</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26772">#26772</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>[<code>flake8-pyi</code>] Fix false positive in <code>__all__</code>
(<code>PYI053</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26872">#26872</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>pylint</code>] Ignore mutable type updates in
<code>redefined-loop-name</code> (<code>PLW2901</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25733">#25733</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid redundant lexer token bookkeeping (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26765">#26765</a>)</li>
<li>Avoid redundant pending-indentation writes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26774">#26774</a>)</li>
<li>Avoid unnecessary identifier lookahead (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26525">#26525</a>)</li>
<li>Reuse parser scratch buffers (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26798">#26798</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Document argfile support (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26803">#26803</a>)</li>
<li>[<code>flake8-datetimez</code>] Clarify naming guidance for
<code>datetime.today</code> (<code>DTZ002</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26658">#26658</a>)</li>
<li>[<code>pycodestyle</code>] Document <code>E731</code> fix safety (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26847">#26847</a>)</li>
<li>[<code>ruff</code>] Clarify intentional async contexts for
<code>unused-async</code> (<code>RUF029</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26641">#26641</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/dwego"><code>@​dwego</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a href="https://github.com/Joosboy"><code>@​Joosboy</code></a></li>
<li><a
href="https://github.com/KaufmanDmitriy"><code>@​KaufmanDmitriy</code></a></li>
<li><a
href="https://github.com/PeterJCLaw"><code>@​PeterJCLaw</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/charliermarsh"><code>@​charliermarsh</code></a></li>
</ul>
<h2>Install ruff 0.15.22</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.22</h2>
<p>Released on 2026-07-16.</p>
<h3>Preview features</h3>
<ul>
<li>[<code>pycodestyle</code>] Add an autofix for <code>E402</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/22212">#22212</a>)</li>
<li>[<code>refurb</code>] Allow subclassing builtins in stub files
(<code>FURB189</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26812">#26812</a>)</li>
<li>[<code>ruff</code>] Add rule to replace <code>noqa</code> comments
with <code>ruff:ignore</code> (<code>RUF105</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26423">#26423</a>)</li>
<li>[<code>ruff</code>] Add rule to use human-readable names in
<code>ruff:ignore</code> comments (<code>RUF106</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26682">#26682</a>)</li>
<li>[<code>ruff</code>] Add rule to use human-readable names in
configuration selectors (<code>RUF201</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26772">#26772</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>[<code>flake8-pyi</code>] Fix false positive in <code>__all__</code>
(<code>PYI053</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26872">#26872</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>pylint</code>] Ignore mutable type updates in
<code>redefined-loop-name</code> (<code>PLW2901</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25733">#25733</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid redundant lexer token bookkeeping (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26765">#26765</a>)</li>
<li>Avoid redundant pending-indentation writes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26774">#26774</a>)</li>
<li>Avoid unnecessary identifier lookahead (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26525">#26525</a>)</li>
<li>Reuse parser scratch buffers (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26798">#26798</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Document argfile support (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26803">#26803</a>)</li>
<li>[<code>flake8-datetimez</code>] Clarify naming guidance for
<code>datetime.today</code> (<code>DTZ002</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26658">#26658</a>)</li>
<li>[<code>pycodestyle</code>] Document <code>E731</code> fix safety (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26847">#26847</a>)</li>
<li>[<code>ruff</code>] Clarify intentional async contexts for
<code>unused-async</code> (<code>RUF029</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26641">#26641</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/dwego"><code>@​dwego</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a href="https://github.com/Joosboy"><code>@​Joosboy</code></a></li>
<li><a
href="https://github.com/KaufmanDmitriy"><code>@​KaufmanDmitriy</code></a></li>
<li><a
href="https://github.com/PeterJCLaw"><code>@​PeterJCLaw</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/charliermarsh"><code>@​charliermarsh</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/ruff/commit/0177a7e0d2c4a3805afa1960f106d72878766cbc"><code>0177a7e</code></a>
Bump 0.15.22 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26884">#26884</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/fe8ba85a55b76d838e6058d813b64468b5f81eca"><code>fe8ba85</code></a>
[<code>pycodestyle</code>] Document <code>E731</code> fix safety (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26847">#26847</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/f3cf7c81fa35f8b819a719303bf1789714f1c780"><code>f3cf7c8</code></a>
[<code>ruff</code>] Add <code>rule-codes-in-selectors</code>
(<code>RUF201</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26772">#26772</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/d244fd75e9036e61be4896b823fe760d7aa632a3"><code>d244fd7</code></a>
Document argfile support (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26803">#26803</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/f23975849a0db64a2851029c68fc054799d5e7da"><code>f239758</code></a>
[<code>flake8-pyi</code>] Fix false positive in <code>__all__</code>
(<code>PYI053</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26872">#26872</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/54acbcde56d76bc47b0b3dfe61e57fbaadd2c06b"><code>54acbcd</code></a>
[ty] Support <code>TypeVarTuple</code> and <code>Unpack</code> (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25240">#25240</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/87fc38cacd7e2bd906674c6dc5b8be97aa3a5bc3"><code>87fc38c</code></a>
[ty] Parallelize subtype hierarchy search (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26875">#26875</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/e454f91fa63bd745d874ead751ad15d9f521195a"><code>e454f91</code></a>
[ty] Share interned query keys across Salsa queries (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26794">#26794</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/6f361a74a232ad283cc6e5e5d3a62109802aab65"><code>6f361a7</code></a>
[ty] only collect expected types for files open in the editor (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25546">#25546</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/6d6b2b37686da8b1ee56e54fd99831f1f5fa0381"><code>6d6b2b3</code></a>
[ty] Avoid allocations during Salsa interned lookups (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26877">#26877</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.15.21...0.15.22">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 15:40:08 -04:00
dependabot[bot]andCaliBrain 28969ac828 Bump the npm-deps group across 1 directory with 7 updates (#1112)
Bumps the npm-deps group with 7 updates in the /src/frontend directory:

| Package | From | To |
| --- | --- | --- |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `26.0.1` | `26.1.1` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) |
`6.23.0` | `6.26.0` |
| [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) |
`0.57.0` | `0.58.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) |
`1.72.0` | `1.73.0` |
| [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) | `0.23.0`
| `0.24.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.1.0` | `8.1.4` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.9` | `4.1.10` |


Updates `@types/node` from 26.0.1 to 26.1.1
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.23.0 to 6.26.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.26.0</h2>
<ul>
<li>ci: add path filters (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1871">#1871</a>)
(4249935adffe1b8eca9570fb325fa19cc8010584) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>Add CodeRabbit as gold sponsor
(1da09fdc8f4d851f3cad30659200018bfb47a5e0)</li>
<li>Fix up docs a bit more
(39125a7f473e006f61629781bff1ac4a050ca460)</li>
<li>Don't report ambient declaration files as unused
(aed361c00a82829c2fc80a65a2f7af174316782e)</li>
<li>Register oclif command files as entries
(3b4d58c9da83d93b6821a2b24f57b919ba886756)</li>
<li>Add electron-vite plugin
(d92107ea504833b3ee7ad2b695e22d40528b24c3)</li>
<li>Add esbuild plugin (ef3b601d957546554de2cb1fbff859f5bdafb741)</li>
<li>Ignore more globally available binaries
(829298129fdfd1b41a1f8dff5022b9fbbe25f454)</li>
<li>Resolve <code>#</code>-imports to source when node condition is
unbuilt (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1873">#1873</a>)
(f2713ed1e499ab286b86615d4b8ec34f711d1bd2)</li>
<li>Ignore gh as a globally available binary
(a6f0772e5db03a8412a3ac036756779f22d1a27d)</li>
<li>Resolve Vitest benchmark files as entries
(57429139f7e93f2a4bee35a53d450c4f45dea9ff)</li>
<li>Extract shared Vue auto-import machinery into plugins/_vue
(73010753d432ae58eb12c7eec9c5723036009749)</li>
<li>Scope compiler extensions per workspace
(5e6f82b963a83e5801484efbc01a4b6a9ce39ea3)</li>
<li>Resolve auto-imported components in the Vue SFC compiler
(009aad8f9dab589898e5dba4c85fa41ea57c1a49)</li>
<li>Add plugins for the Vue auto-import ecosystem
(f638c8302cdd26a63e477344a7cf44ef60af7788)</li>
<li>Enable Vue SFC compiler on unplugin-vue and
<code>@​vitejs/plugin-vue</code>
(9396ab159919147ef81dad16e365e531b32b4b12)</li>
<li>Recognize vite-plugin-vue-meta-layouts (same layouts convention)
(3ceee89228b0173eddc0466bf50e8181286ffebc)</li>
<li>Add vite-plugin-pages and unplugin-icons plugins
(9bc17540bcf8eb142474ed84837c1e2cebb7fe73)</li>
<li>Add vite-plugin-pwa and <code>@​intlify/unplugin-vue-i18n</code>
plugins (45dea0a397ed754c34617ed18deef4dc6f0ec0d4)</li>
<li>Dog, food. (e1249ade2558d3801d85e2dc63349d884f3443d4)</li>
<li>Update query snapshot
(a45941d2db381c04f8a38416533217ee84f77ca7)</li>
<li>Don't misread Nitro route types as Vue component auto-imports
(43aecd5414eb63bec3637f37ffac0c62a71e7e74)</li>
<li>Read oxlint jsPlugins from vite-plus vite.config and .oxlintrc.json
(589ffda4e3a7d0c0d772191ad6f8d6e60dd298cf)</li>
<li>Add vite-plus plugin for run.tasks and staged scripts
(f041c191e4e10dd181ad212b71079e3e10bcf341)</li>
<li>Support <code>@​vite-pwa/nuxt</code> PWA config in nuxt.config
(8fa7b116690e37484798ad98eca002d26c0c80fe)</li>
<li>Add <code>@​vite-pwa/assets-generator</code> plugin
(4254f7d53a284a4ea4612f650ae03495bcb0d582)</li>
<li>Add <code>@​nuxtjs/i18n</code> plugin
(dfb9acbe5a08ebc85562f59a04e7f4bedb4925f1)</li>
<li>Read plugin entries from vite.config options and index.html
(d533da8cc2b431d206eb7c55323ea51846eca0bb)</li>
<li>Fix false positives in VitePress, next-mdx and unplugin-vue-i18n
plugins (b99702a76e26b1943a16517f1633de3a0713c196)</li>
<li>Respect optional peers in pnpm and Yarn packageExtensions
(aab080bbd436494316df045011ab22cbebca06b4)</li>
<li>Detect babel plugins in the Storybook config
(5dea975adf9b88971ad56434132282a099c7d58c)</li>
<li>Add shared AST helpers for imported calls and first property values
(c84bb7a87a17f1921c12bb02bcfd43f905cae595)</li>
<li>Inline trivial resolveFromAST wrappers and normalize orval and sst
(620079d1d07b69a69bbb67b6a6e68963b6c2fc21)</li>
<li>Extract inline resolveFromAST implementations to dedicated files
(b5231c12f915428067d790187d2dd4c44e2559d4)</li>
<li>Normalize resolveFromAST files to a uniform contract
(fc1ba0fb45aaf623de678a57bea3b5567ea04750)</li>
<li>chore: migrate to Astro 7 and Sätteri (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1875">#1875</a>)
(f256a5b276c3d69dd5081c591bbb183aacebf766) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>Show contributor count on docs homepage
(6b8454a2841905ce7f08e1a23b54bc17a0854608)</li>
<li>Exclude gitignored package entry points
(606e5d051b4f0620c776aa23352153b8253bd75b)</li>
<li>Add Tauri plugin (199180da79c71acc80865dc65ce89653a26d9579)</li>
<li>Add Laravel plugin (197453378f2b60e5143a30ec78b438f02b37c53b)</li>
<li>Add Quasar plugin (a220729074bfbb9e7d03ba329e89ad553c3a7799)</li>
</ul>
<h2>Release 6.25.0</h2>
<ul>
<li>fix: derive package name from package.json under Yarn
<code>nodeLinker: pnpm</code> store (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1852">#1852</a>)
(3764605ed150b975fb6c88c4c4aa47f5bf9ae149) - thanks <a
href="https://github.com/blowery"><code>@​blowery</code></a>!</li>
<li>Pick up types used in module augmentations via path aliases (resolve
<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1850">#1850</a>)
(9cc5a4132793990b5fcf9eae6f3db37426d979c0)</li>
<li>feat: add support for <code>packageExtensions</code> in yarn and
pnpm (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1847">#1847</a>)
(61d3164cdac6e9252b3c52ce3bb2909949b4690e) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>fix(ci): do not run integration on forks (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1855">#1855</a>)
(d23c10d1ae764c0b70addaafc79f01c543cc5efa) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>chore(ci): improve security through specific permissions (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1856">#1856</a>)
(1eb42e639f9ec12d6d2ef88e1aaf07397b5bf226) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>chore(ci): add concurrency blocks (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1857">#1857</a>)
(3bf3d115cf677fadcfe8fa72ce0e68cfd435d399) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/441faf08dfa1e87daa342620026947c99a98ec40"><code>441faf0</code></a>
Release knip@6.26.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/a220729074bfbb9e7d03ba329e89ad553c3a7799"><code>a220729</code></a>
Add Quasar plugin</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/197453378f2b60e5143a30ec78b438f02b37c53b"><code>1974533</code></a>
Add Laravel plugin</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/199180da79c71acc80865dc65ce89653a26d9579"><code>199180d</code></a>
Add Tauri plugin</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/606e5d051b4f0620c776aa23352153b8253bd75b"><code>606e5d0</code></a>
Exclude gitignored package entry points</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/fc1ba0fb45aaf623de678a57bea3b5567ea04750"><code>fc1ba0f</code></a>
Normalize resolveFromAST files to a uniform contract</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/b5231c12f915428067d790187d2dd4c44e2559d4"><code>b5231c1</code></a>
Extract inline resolveFromAST implementations to dedicated files</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/620079d1d07b69a69bbb67b6a6e68963b6c2fc21"><code>620079d</code></a>
Inline trivial resolveFromAST wrappers and normalize orval and sst</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/c84bb7a87a17f1921c12bb02bcfd43f905cae595"><code>c84bb7a</code></a>
Add shared AST helpers for imported calls and first property values</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/5dea975adf9b88971ad56434132282a099c7d58c"><code>5dea975</code></a>
Detect babel plugins in the Storybook config</li>
<li>Additional commits viewable in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.26.0/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.57.0 to 0.58.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/39677ba50d908ea09f6d9e58ded328461212f52a"><code>39677ba</code></a>
release(apps): oxlint v1.73.0 &amp;&amp; oxfmt v0.58.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/24219">#24219</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.58.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.72.0 to 1.73.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.73.0] - 2026-07-06</h2>
<h3>🚀 Features</h3>
<ul>
<li>a2c97f3 linter/unicorn: Implement <code>explicit-timer-delay</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23612">#23612</a>)
(Mikhail Baev)</li>
<li>85735cb linter/unicorn: Implement
<code>no-confusing-array-with</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23638">#23638</a>)
(Shekhu☺️)</li>
<li>cb4fbb9 linter/eslint: Implement no-unreachable-loop rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23975">#23975</a>)
(Todor Andonov)</li>
<li>dc32112 linter/eslint/no-constant-binary-expression: Check
relational comparisons (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24088">#24088</a>)
(camc314)</li>
<li>d963967 linter/unicorn/no-array-sort: Add
<code>allowAfterSpread</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24043">#24043</a>)
(Boshen)</li>
<li>0a75682 linter: Add per-rule timings for type-aware linting (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22488">#22488</a>)
(camchenry)</li>
<li>743e222 linter/react: Add <code>disallowedValues</code> option for
<code>forbid-dom-props</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23970">#23970</a>)
(Mikhail Baev)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>bdb51c7 linter/jest/prefer-ending-with-an-expect: Validate config
patterns (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24122">#24122</a>)
(camc314)</li>
<li>45d607d linter/react/forbid-component-props: Make allow/disallow
lists optional in schema (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24024">#24024</a>)
(Boshen)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/39677ba50d908ea09f6d9e58ded328461212f52a"><code>39677ba</code></a>
release(apps): oxlint v1.73.0 &amp;&amp; oxfmt v0.58.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24219">#24219</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/a2c97f348c8bdabe99a08b2fbb45d32ffe49a529"><code>a2c97f3</code></a>
feat(linter/unicorn): implement <code>explicit-timer-delay</code> rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23612">#23612</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/bdb51c73da9edeef02ce39477167765d971fb5cb"><code>bdb51c7</code></a>
fix(linter/jest/prefer-ending-with-an-expect): validate config patterns
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24122">#24122</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/85735cb5df27daffd32651f808a382680ee92aaf"><code>85735cb</code></a>
feat(linter/unicorn): implement <code>no-confusing-array-with</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23638">#23638</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/cb4fbb927f237b0ba4937a8de5a7b28c444b4114"><code>cb4fbb9</code></a>
feat(linter/eslint): implement no-unreachable-loop rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23975">#23975</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/dc321127faa1e0f7bff293319717c52f9c8f6b95"><code>dc32112</code></a>
feat(linter/eslint/no-constant-binary-expression): check relational
compariso...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/d96396707923bcffa92e732b15bf23631561f35c"><code>d963967</code></a>
feat(linter/unicorn/no-array-sort): add <code>allowAfterSpread</code>
option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/24043">#24043</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/45d607d48529dc9f32f53436ee816fc02494c64b"><code>45d607d</code></a>
fix(linter/react/forbid-component-props): make allow/disallow lists
optional ...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/0a75682fcb38014878d53f37075f32e12101e265"><code>0a75682</code></a>
feat(linter): add per-rule timings for type-aware linting (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22488">#22488</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/743e22293bc5317c79b6b083ffbb2bd5ab5ebefc"><code>743e222</code></a>
feat(linter/react): add <code>disallowedValues</code> option for
<code>forbid-dom-props</code> rule...</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.73.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint-tsgolint` from 0.23.0 to 0.24.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/tsgolint/releases">oxlint-tsgolint's
releases</a>.</em></p>
<blockquote>
<h2>v0.24.0</h2>
<h2>What's Changed</h2>
<ul>
<li>ci: run windows e2e pnpm commands outside workspace by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/969">oxc-project/tsgolint#969</a></li>
<li>test(no-deprecated): add test for only <code>allow</code> by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/970">oxc-project/tsgolint#970</a></li>
<li>fix(no-deprecated): report contextual object literal properties by
<a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/944">oxc-project/tsgolint#944</a></li>
<li>Update README with PRs note on new rules by <a
href="https://github.com/camchenry"><code>@​camchenry</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/972">oxc-project/tsgolint#972</a></li>
<li>fix(strict-boolean-expressions): guard invalid predicate indexes by
<a href="https://github.com/camchenry"><code>@​camchenry</code></a> in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/971">oxc-project/tsgolint#971</a></li>
<li>fix(no-deprecated): fix crash when getting prop name for non-literal
by <a href="https://github.com/camchenry"><code>@​camchenry</code></a>
in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/973">oxc-project/tsgolint#973</a></li>
<li>test(no-deprecated): add non-literal computed key regression by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/974">oxc-project/tsgolint#974</a></li>
<li>test(no-floating-promises): sync tests with typescript-eslint by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/975">oxc-project/tsgolint#975</a></li>
<li>fix(no-floating-promises): handle spread arguments before rejection
handlers by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/976">oxc-project/tsgolint#976</a></li>
<li>chore(deps): update crate-ci/typos action to v1.46.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/979">oxc-project/tsgolint#979</a></li>
<li>refactor: remove unneeded <code>nil</code> checks in
<code>strict-boolean-expressions</code> by <a
href="https://github.com/camchenry"><code>@​camchenry</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/980">oxc-project/tsgolint#980</a></li>
<li>perf(no-unsafe-assignment): add fast-path for sender type by <a
href="https://github.com/camchenry"><code>@​camchenry</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/981">oxc-project/tsgolint#981</a></li>
<li>feat: add per-rule debug timings by <a
href="https://github.com/camchenry"><code>@​camchenry</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/960">oxc-project/tsgolint#960</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/982">oxc-project/tsgolint#982</a></li>
<li>chore(deps): update dprint plugins by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/984">oxc-project/tsgolint#984</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/985">oxc-project/tsgolint#985</a></li>
<li>chore(deps): update gomod by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/986">oxc-project/tsgolint#986</a></li>
<li>chore(deps): update crate-ci/typos action to v1.46.3 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/988">oxc-project/tsgolint#988</a></li>
<li>test(no-deprecated): cover call and jsx deprecated properties by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/989">oxc-project/tsgolint#989</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/991">oxc-project/tsgolint#991</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/993">oxc-project/tsgolint#993</a></li>
<li>chore(deps): update crate-ci/typos action to v1.47.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/995">oxc-project/tsgolint#995</a></li>
<li>chore(deps): update module github.com/dlclark/regexp2/v2 to v2.1.1
by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/994">oxc-project/tsgolint#994</a></li>
<li>fix(prefer-optional-chain): suggest unsafe nullish rewrite by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/996">oxc-project/tsgolint#996</a></li>
<li>chore(deps): update pnpm to v11.4.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/997">oxc-project/tsgolint#997</a></li>
<li>refactor: cache suppress program diagnostics env by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/999">oxc-project/tsgolint#999</a></li>
<li>refactor: use <code>sync.OnceValue</code> for logLevel by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1000">oxc-project/tsgolint#1000</a></li>
<li>test(no-unnecessary-type-assertion): sync tests with
typescript-eslint by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/998">oxc-project/tsgolint#998</a></li>
<li>fix(no-unnecessary-type-assertion): enable skipped upstream cases by
<a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1001">oxc-project/tsgolint#1001</a></li>
<li>fix(justfile): use --ignore-workspace for e2e pnpm commands by <a
href="https://github.com/swandir"><code>@​swandir</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/983">oxc-project/tsgolint#983</a></li>
<li>test(no-unnecessary-type-arguments): sync tests with
typescript-eslint by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1003">oxc-project/tsgolint#1003</a></li>
<li>test(no-unnecessary-type-assertion): cover nullable literal
assertion by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1002">oxc-project/tsgolint#1002</a></li>
<li>fix(no-unnecessary-type-arguments): preserve constructor inference
by <a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1004">oxc-project/tsgolint#1004</a></li>
<li>refactor: remove <code>OXLINT_TSGOLINT_TIMINGS</code> env var by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1005">oxc-project/tsgolint#1005</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1007">oxc-project/tsgolint#1007</a></li>
<li>fix(prefer-optional-chain): optional chain type assertion handling
by <a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1009">oxc-project/tsgolint#1009</a></li>
<li>chore(deps): update typos to v1.47.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1010">oxc-project/tsgolint#1010</a></li>
<li>chore(deps): update typos to v1.47.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1012">oxc-project/tsgolint#1012</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1013">oxc-project/tsgolint#1013</a></li>
<li>chore(deps): update gomod by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1014">oxc-project/tsgolint#1014</a></li>
<li>chore(deps): update github actions to v2.81.5 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1015">oxc-project/tsgolint#1015</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1016">oxc-project/tsgolint#1016</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1017">oxc-project/tsgolint#1017</a></li>
<li>chore(deps): update gomod to v0.46.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1018">oxc-project/tsgolint#1018</a></li>
<li>chore(deps): update gomod to v2.2.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1021">oxc-project/tsgolint#1021</a></li>
<li>chore(deps): update github actions to v2.82.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1023">oxc-project/tsgolint#1023</a></li>
<li>chore(deps): update dprint plugins to v0.22.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1022">oxc-project/tsgolint#1022</a></li>
<li>chore(deps): update github actions to v7 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/1024">oxc-project/tsgolint#1024</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/5a37e8902f65440900be1436b814919fcdb4e3d4"><code>5a37e89</code></a>
fix(dot-notation): determine the relevant accessor (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1028">#1028</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/67a281f613312a30665e7d39dfb47f5c15b0ca60"><code>67a281f</code></a>
perf(consistent-return): defer per-function type resolution (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1031">#1031</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/a5e2ff0be1102d9082e13ec35f1f0e4ca7fa65ad"><code>a5e2ff0</code></a>
perf(no-unnecessary-qualifier): skip symbol resolution outside
namespaces. (#...</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/a8fc6685df0a817e7c5045a4e3e141d342839959"><code>a8fc668</code></a>
perf(no-confusing-void-expression): check ancestor position before type
query...</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/03158cc4c0a0ef2c8bdccab71e6d2723fcc1c4f2"><code>03158cc</code></a>
perf(no-unnecessary-type-conversion): hoist constant builtin-name slices
(<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1040">#1040</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/d9e645c266b6c4b4671b0a3dc5d3935dbda3a5ef"><code>d9e645c</code></a>
perf(prefer-optional-chain): lazily allocate chain-processor caches (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1041">#1041</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/63f578abe093d7a7e8cb523a1e5e96aacf06b220"><code>63f578a</code></a>
refactor(no-unnecessary-condition): remove dead
containsUnguardedElementAcces...</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/f174876a906e0350aff2b75d5607775529c9f845"><code>f174876</code></a>
chore(deps): update gomod (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1035">#1035</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/47de9cfea53da0ae274bc78d47388e3bdd5b7341"><code>47de9cf</code></a>
chore(deps): update github actions (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1036">#1036</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/e209b5b27f5fd22810735bfbfdb0785cbc5d4215"><code>e209b5b</code></a>
chore(deps): update actions/cache action to v6 (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/1037">#1037</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/tsgolint/compare/v0.23.0...v0.24.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.1.0 to 8.1.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v8.1.4</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.4/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.3</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.3/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.2</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.2/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.1</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.1/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.1.3...v8.1.4">8.1.4</a>
(2026-07-09)<!-- raw HTML omitted --></h2>
<h3>Features</h3>
<ul>
<li><strong>legacy:</strong> prefer oxc as minifier (fix <a
href="https://redirect.github.com/vitejs/vite/issues/21973">#21973</a>)
(<a
href="https://redirect.github.com/vitejs/vite/issues/22468">#22468</a>)
(<a
href="https://github.com/vitejs/vite/commit/ab5dafa8e66296ef201f615489fb57954bb740ce">ab5dafa</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>build:</strong> add workaround for building on stackblitz
(<a
href="https://redirect.github.com/vitejs/vite/issues/22840">#22840</a>)
(<a
href="https://github.com/vitejs/vite/commit/575c32c29925c554f4ef4068738ab89c6878f615">575c32c</a>)</li>
<li><strong>build:</strong> keep <code>import.meta.url</code> in preload
function as-is (<a
href="https://redirect.github.com/vitejs/vite/issues/22839">#22839</a>)
(<a
href="https://github.com/vitejs/vite/commit/f1f90ed4742b3cf453428c7e581a6016a4d47321">f1f90ed</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22865">#22865</a>)
(<a
href="https://github.com/vitejs/vite/commit/d4295a9ffce428c0e51892373e00c07fccc0498a">d4295a9</a>)</li>
<li><strong>deps:</strong> update rolldown-related dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22866">#22866</a>)
(<a
href="https://github.com/vitejs/vite/commit/7cf07e4c5f7a6af276012e0c2ec06e08499e951e">7cf07e4</a>)</li>
<li><strong>html:</strong> avoid backtracking in import-only check (<a
href="https://redirect.github.com/vitejs/vite/issues/22848">#22848</a>)
(<a
href="https://github.com/vitejs/vite/commit/b5868c01a124d345664450aaebd677bfba964c05">b5868c0</a>)</li>
<li><strong>optimizer:</strong> avoid optimizer run for transform
request before init (<a
href="https://redirect.github.com/vitejs/vite/issues/22852">#22852</a>)
(<a
href="https://github.com/vitejs/vite/commit/72a5e2192506f51a5efd09c059815a5c43a9eacb">72a5e21</a>)</li>
<li><strong>ssr:</strong> align named export function call stacktrace
column with Node (<a
href="https://redirect.github.com/vitejs/vite/issues/22829">#22829</a>)
(<a
href="https://github.com/vitejs/vite/commit/173a1b648c321e0f836e5a94fc47c4fa9b081bfc">173a1b6</a>)</li>
<li>strip pure CSS chunk imports when chunkImportMap is enabled (<a
href="https://redirect.github.com/vitejs/vite/issues/22841">#22841</a>)
(<a
href="https://github.com/vitejs/vite/commit/648bd04933093d0aac9565f21a49811437776886">648bd04</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>fix incorrect <code>@default</code> for <code>server.cors</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22859">#22859</a>)
(<a
href="https://github.com/vitejs/vite/commit/70435b2551ee4fe3a0d55c8a3bb61b96f44d2763">70435b2</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li><strong>deps:</strong> update dependency postcss-modules to v9 (<a
href="https://redirect.github.com/vitejs/vite/issues/22867">#22867</a>)
(<a
href="https://github.com/vitejs/vite/commit/a9539d69efc7a4ccf988bbf5da31c2b416ba990e">a9539d6</a>)</li>
</ul>
<h3>Code Refactoring</h3>
<ul>
<li>eliminate ineffectiveDynamicImport warn (<a
href="https://redirect.github.com/vitejs/vite/issues/22876">#22876</a>)
(<a
href="https://github.com/vitejs/vite/commit/ea22fb352aad9a42c0a9d08f39d8a0bae8c111a5">ea22fb3</a>)</li>
</ul>
<h3>Tests</h3>
<ul>
<li>avoid warnings (<a
href="https://redirect.github.com/vitejs/vite/issues/22851">#22851</a>)
(<a
href="https://github.com/vitejs/vite/commit/af21ab68adac3380dc9a854d2fe3f776654301cd">af21ab6</a>)</li>
</ul>
<h3>Build System</h3>
<ul>
<li>remove the custom onLog function (<a
href="https://redirect.github.com/vitejs/vite/issues/22878">#22878</a>)
(<a
href="https://github.com/vitejs/vite/commit/2c4a217a63dc0a7fcb10bc710a988f32b173f481">2c4a217</a>)</li>
<li>replace deprecated <code>onwarn</code> with <code>onLog</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22741">#22741</a>)
(<a
href="https://github.com/vitejs/vite/commit/c581b5588cb8e94603d17bce2ff9fec8e8e0a3bf">c581b55</a>)</li>
</ul>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.1.2...v8.1.3">8.1.3</a>
(2026-07-02)<!-- raw HTML omitted --></h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>css:</strong> inject inlined CSS after the shebang line (<a
href="https://redirect.github.com/vitejs/vite/issues/22717">#22717</a>)
(<a
href="https://github.com/vitejs/vite/commit/1534d362794e856cc718b123cb245e0efcf36b9a">1534d36</a>)</li>
<li><strong>deps:</strong> bump <code>es-module-lexer</code> to 2.3.0
(<a
href="https://redirect.github.com/vitejs/vite/issues/22838">#22838</a>)
(<a
href="https://github.com/vitejs/vite/commit/7103c3af795396e2ad87e1125eb3fc20d60d9430">7103c3a</a>)</li>
<li>preload css for nested dynamic imports (<a
href="https://redirect.github.com/vitejs/vite/issues/22759">#22759</a>)
(<a
href="https://github.com/vitejs/vite/commit/2c530542da1c50b95b7f0cb17adf82f64ecf97f3">2c53054</a>)</li>
<li><strong>ssr:</strong> correct stacktrace column position for first
line (<a
href="https://redirect.github.com/vitejs/vite/issues/22828">#22828</a>)
(<a
href="https://github.com/vitejs/vite/commit/c4acd6982a051fa10dbd7e3a37e00f0c467793b8">c4acd69</a>)</li>
</ul>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.1.1...v8.1.2">8.1.2</a>
(2026-06-30)<!-- raw HTML omitted --></h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>deps:</strong> revert es-module-lexer to 2.1.0 (<a
href="https://redirect.github.com/vitejs/vite/issues/22827">#22827</a>)
(<a
href="https://github.com/vitejs/vite/commit/0d3bd7c4111b8345cfc353c7bbb2c30601752e26">0d3bd7c</a>)</li>
<li>restore, &quot;fix: resolve pnpm .modules.yaml from workspace root
instead of cwd (<a
href="https://redirect.github.com/vitejs/vite/issues/22757">#22757</a>)&quot;
(<a
href="https://redirect.github.com/vitejs/vite/issues/22825">#22825</a>)
(<a
href="https://github.com/vitejs/vite/commit/efb98cce73f3f89c4f03936ab7741cd5b0636f5c">efb98cc</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/a477454442eff649b430f9e3c6caf2500fcb7183"><code>a477454</code></a>
release: v8.1.4</li>
<li><a
href="https://github.com/vitejs/vite/commit/ab5dafa8e66296ef201f615489fb57954bb740ce"><code>ab5dafa</code></a>
feat(legacy): prefer oxc as minifier (fix <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21973">#21973</a>)
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22468">#22468</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/173a1b648c321e0f836e5a94fc47c4fa9b081bfc"><code>173a1b6</code></a>
fix(ssr): align named export function call stacktrace column with Node
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22829">#22829</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/575c32c29925c554f4ef4068738ab89c6878f615"><code>575c32c</code></a>
fix(build): add workaround for building on stackblitz (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22840">#22840</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/72a5e2192506f51a5efd09c059815a5c43a9eacb"><code>72a5e21</code></a>
fix(optimizer): avoid optimizer run for transform request before init
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22852">#22852</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/a9539d69efc7a4ccf988bbf5da31c2b416ba990e"><code>a9539d6</code></a>
chore(deps): update dependency postcss-modules to v9 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22867">#22867</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/70435b2551ee4fe3a0d55c8a3bb61b96f44d2763"><code>70435b2</code></a>
docs: fix incorrect <code>@default</code> for <code>server.cors</code>
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22859">#22859</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/2c4a217a63dc0a7fcb10bc710a988f32b173f481"><code>2c4a217</code></a>
build: remove the custom onLog function (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22878">#22878</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/c581b5588cb8e94603d17bce2ff9fec8e8e0a3bf"><code>c581b55</code></a>
build: replace deprecated <code>onwarn</code> with <code>onLog</code>
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22741">#22741</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/ea22fb352aad9a42c0a9d08f39d8a0bae8c111a5"><code>ea22fb3</code></a>
refactor: eliminate ineffectiveDynamicImport warn (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22876">#22876</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/v8.1.4/packages/vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 4.1.9 to 4.1.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.10</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Check fs access in builtin commands
[backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode
(claude-opus-4-8)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10680">vitest-dev/vitest#10680</a>
<a href="https://github.com/vitest-dev/vitest/commit/5c18dd267"><!-- raw
HTML omitted -->(5c18d)<!-- raw HTML omitted --></a></li>
<li><strong>vm</strong>: Fix external module resolve error with deps
optimizer query for encoded URI [backport to v4]  -  by <a
href="https://github.com/SveLil"><code>@​SveLil</code></a> and <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10661">vitest-dev/vitest#10661</a>
<a href="https://github.com/vitest-dev/vitest/commit/bae52b511"><!-- raw
HTML omitted -->(bae52)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46"><code>db616d2</code></a>
chore: release v4.1.10 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10718">#10718</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/bae52b5112a6fd8200101b88bf8af9685d077295"><code>bae52b5</code></a>
fix(vm): fix external module resolve error with deps optimizer query for
enco...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-07-19 03:29:15 -04:00
dependabot[bot] 2f5d3dde7d Bump seleniumbase from 4.50.6 to 4.51.0 in the python-deps group (#1118)
Bumps the python-deps group with 1 update:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase).

Updates `seleniumbase` from 4.50.6 to 4.51.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.51.0 - CDP Mode: Patch 119</h2>
<h2>CDP Mode: Patch 119</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/5ca71c54fa8e22004591788a7d76aa77add3fccf">Update
CDP Mode</a>
--&gt; New methods for logging from CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a1a0cdf6476505a5fb10190196ced67487749879">Don't
ignore the cache by default on reload()</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/97b6bf3fef6d3cda8835a1af730c31e06ee27505">Update
the docs</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/775a91bc1843508b9655af396585de376b558e7b">Update
examples</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/6f38a2469aa9122eeb188ea683f5b39a55753ee5">Refresh
Python dependencies</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 119 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4422">seleniumbase/SeleniumBase#4422</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.6...v4.51.0">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.6...v4.51.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/36627158b4a395a3793dd97e762e282dc97e2a54"><code>3662715</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4422">#4422</a>
from seleniumbase/cdp-mode-patch-119</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/78abd3effed503e5abfa64fd5697a556229dfe02"><code>78abd3e</code></a>
Version 4.51.0</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/6f38a2469aa9122eeb188ea683f5b39a55753ee5"><code>6f38a24</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/775a91bc1843508b9655af396585de376b558e7b"><code>775a91b</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/97b6bf3fef6d3cda8835a1af730c31e06ee27505"><code>97b6bf3</code></a>
Update the docs</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a1a0cdf6476505a5fb10190196ced67487749879"><code>a1a0cdf</code></a>
Don't ignore the cache by default on reload()</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/5ca71c54fa8e22004591788a7d76aa77add3fccf"><code>5ca71c5</code></a>
Update CDP Mode</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.6...v4.51.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=seleniumbase&package-manager=uv&previous-version=4.50.6&new-version=4.51.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-19 02:52:13 -04:00
dependabot[bot] 2d949d4e7c Bump python from b877e50 to d3400aa (#1119)
Bumps python from `b877e50` to `d3400aa`.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.14.6-slim&new-version=3.14.6-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-19 02:52:03 -04:00
dependabot[bot] 100e0dd9f8 Bump the gh-actions group across 1 directory with 10 updates (#1120)
Bumps the gh-actions group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [docker/login-action](https://github.com/docker/login-action) |
`4.2.0` | `4.4.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) |
`6.1.0` | `6.2.0` |
|
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action)
| `4.1.0` | `4.2.0` |
|
[docker/build-push-action](https://github.com/docker/build-push-action)
| `7.2.0` | `7.3.0` |
| [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `8.2.0`
| `8.3.2` |
| [actions/setup-node](https://github.com/actions/setup-node) | `6.4.0`
| `7.0.0` |
| [github/codeql-action/init](https://github.com/github/codeql-action) |
`4.36.2` | `4.37.0` |
|
[github/codeql-action/autobuild](https://github.com/github/codeql-action)
| `4.36.2` | `4.37.0` |
|
[github/codeql-action/analyze](https://github.com/github/codeql-action)
| `4.36.2` | `4.37.0` |
| [dorny/paths-filter](https://github.com/dorny/paths-filter) | `4.0.1`
| `4.0.2` |


Updates `docker/login-action` from 4.2.0 to 4.4.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/login-action/releases">docker/login-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.0</h2>
<ul>
<li>Skip empty <code>registry-auth</code> secret mask by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/login-action/pull/1035">docker/login-action#1035</a></li>
<li>Bump <code>@​aws-sdk/client-ecr</code> and
<code>@​aws-sdk/client-ecr-public</code> to 3.1077.0 <a
href="https://redirect.github.com/docker/login-action/pull/1034">docker/login-action#1034</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/login-action/compare/v4.3.0...v4.4.0">https://github.com/docker/login-action/compare/v4.3.0...v4.4.0</a></p>
<h2>v4.3.0</h2>
<ul>
<li>Preserve names in esbuild bundle by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/login-action/pull/1022">docker/login-action#1022</a></li>
<li>Bump <code>@​aws-sdk/client-ecr</code> and
<code>@​aws-sdk/client-ecr-public</code> to 3.1076.0 <a
href="https://redirect.github.com/docker/login-action/pull/999">docker/login-action#999</a>
<a
href="https://redirect.github.com/docker/login-action/pull/1030">docker/login-action#1030</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.90.0 to 0.92.0 in
<a
href="https://redirect.github.com/docker/login-action/pull/1004">docker/login-action#1004</a>
<a
href="https://redirect.github.com/docker/login-action/pull/1027">docker/login-action#1027</a></li>
<li>Bump <code>@​sigstore/core</code> from 3.1.0 to 3.2.1 in <a
href="https://redirect.github.com/docker/login-action/pull/1023">docker/login-action#1023</a></li>
<li>Bump <code>@​sigstore/verify</code> from 3.1.0 to 3.1.1 in <a
href="https://redirect.github.com/docker/login-action/pull/1029">docker/login-action#1029</a></li>
<li>Bump http-proxy-agent and https-proxy-agent to 9.1.0 in <a
href="https://redirect.github.com/docker/login-action/pull/1017">docker/login-action#1017</a></li>
<li>Bump js-yaml from 4.1.1 to 5.2.0 in <a
href="https://redirect.github.com/docker/login-action/pull/1028">docker/login-action#1028</a></li>
<li>Bump sigstore from 4.1.0 to 4.1.1 in <a
href="https://redirect.github.com/docker/login-action/pull/1031">docker/login-action#1031</a></li>
<li>Bump tmp from 0.2.5 to 0.2.7 in <a
href="https://redirect.github.com/docker/login-action/pull/1002">docker/login-action#1002</a></li>
<li>Bump undici from 6.24.1 to 6.27.0 in <a
href="https://redirect.github.com/docker/login-action/pull/1020">docker/login-action#1020</a></li>
<li>Bump vite from 7.3.3 to 7.3.6 in <a
href="https://redirect.github.com/docker/login-action/pull/1019">docker/login-action#1019</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/login-action/compare/v4.2.0...v4.3.0">https://github.com/docker/login-action/compare/v4.2.0...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/login-action/commit/af1e73f918a031802d376d3c8bbc3fe56130a9b0"><code>af1e73f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/1034">#1034</a>
from docker/dependabot/npm_and_yarn/aws-sdk-dependen...</li>
<li><a
href="https://github.com/docker/login-action/commit/da722bde43bacb027adfc67d42dbaa4c0f9e550b"><code>da722bd</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/2916ad60bd5cb72f07aa54c69fdcc61749c09b7a"><code>2916ad6</code></a>
build(deps): bump the aws-sdk-dependencies group across 1 directory with
2 up...</li>
<li><a
href="https://github.com/docker/login-action/commit/ca0a662f786e4cfddce972005bd68f3dafc3a903"><code>ca0a662</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/1035">#1035</a>
from crazy-max/fix-registry-auth-empty-mask</li>
<li><a
href="https://github.com/docker/login-action/commit/c455755a579833bf0d2e4e54e3beb413ef10cc80"><code>c455755</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/48351901f89581a7c12870c787d3f06d1f498438"><code>4835190</code></a>
skip empty registry-auth secret mask</li>
<li><a
href="https://github.com/docker/login-action/commit/992421c6e6806a7f6df609d1bfff374f9eca3004"><code>992421c</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/1033">#1033</a>
from docker/dependabot/github_actions/docker/bake-ac...</li>
<li><a
href="https://github.com/docker/login-action/commit/b249b43765525dd7951068267a34cf63f22ab4f0"><code>b249b43</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/1032">#1032</a>
from docker/dependabot/github_actions/docker/bake-ac...</li>
<li><a
href="https://github.com/docker/login-action/commit/1b67977736863551a88ff218642a2d7628b10520"><code>1b67977</code></a>
build(deps): bump docker/bake-action from 7.2.0 to 7.3.0</li>
<li><a
href="https://github.com/docker/login-action/commit/9d49d6a3234c78daa10c3c12183ef7b6caa8e69e"><code>9d49d6a</code></a>
build(deps): bump docker/bake-action/subaction/matrix</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...af1e73f918a031802d376d3c8bbc3fe56130a9b0">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/metadata-action` from 6.1.0 to 6.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/metadata-action/releases">docker/metadata-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.2.0</h2>
<ul>
<li>Preserve names in esbuild bundle by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/metadata-action/pull/689">docker/metadata-action#689</a></li>
<li>Bump <code>@​actions/core</code> from 3.0.0 to 3.0.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/663">docker/metadata-action#663</a></li>
<li>Bump <code>@​actions/github</code> from 9.0.0 to 9.1.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/666">docker/metadata-action#666</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.90.0 to 0.92.0 in
<a
href="https://redirect.github.com/docker/metadata-action/pull/672">docker/metadata-action#672</a>
<a
href="https://redirect.github.com/docker/metadata-action/pull/696">docker/metadata-action#696</a></li>
<li>Bump <code>@​sigstore/core</code> from 3.1.0 to 3.2.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/690">docker/metadata-action#690</a></li>
<li>Bump <code>@​sigstore/verify</code> from 3.1.0 to 3.1.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/693">docker/metadata-action#693</a></li>
<li>Bump csv-parse from 6.2.1 to 7.0.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/683">docker/metadata-action#683</a></li>
<li>Bump js-yaml from 4.1.1 to 4.3.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/688">docker/metadata-action#688</a></li>
<li>Bump moment-timezone from 0.6.1 to 0.6.2 in <a
href="https://redirect.github.com/docker/metadata-action/pull/664">docker/metadata-action#664</a></li>
<li>Bump semver from 7.7.4 to 7.8.5 in <a
href="https://redirect.github.com/docker/metadata-action/pull/665">docker/metadata-action#665</a>
<a
href="https://redirect.github.com/docker/metadata-action/pull/695">docker/metadata-action#695</a></li>
<li>Bump sigstore from 4.1.0 to 4.1.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/694">docker/metadata-action#694</a></li>
<li>Bump tmp from 0.2.5 to 0.2.7 in <a
href="https://redirect.github.com/docker/metadata-action/pull/673">docker/metadata-action#673</a></li>
<li>Bump undici from 6.25.0 to 6.27.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/686">docker/metadata-action#686</a></li>
<li>Bump vite from 7.3.2 to 7.3.6 in <a
href="https://redirect.github.com/docker/metadata-action/pull/685">docker/metadata-action#685</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/metadata-action/compare/v6.1.0...v6.2.0">https://github.com/docker/metadata-action/compare/v6.1.0...v6.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/metadata-action/commit/dc802804100637a589fabce1cb79ff13a1411302"><code>dc80280</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/696">#696</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/metadata-action/commit/2b9fe830efc58cb7b0fab7c94300b1afa01864db"><code>2b9fe83</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/metadata-action/commit/8128ce30ab370fd360c8423698dcc077f2db8087"><code>8128ce3</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.91.0 to
0.92.0</li>
<li><a
href="https://github.com/docker/metadata-action/commit/1d1c89551edb081628e818368680beffb2bbccee"><code>1d1c895</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/695">#695</a>
from docker/dependabot/npm_and_yarn/semver-7.8.5</li>
<li><a
href="https://github.com/docker/metadata-action/commit/7f0c2dd4c83ea6258f78bf2fc6a02908417518ad"><code>7f0c2dd</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/694">#694</a>
from docker/dependabot/npm_and_yarn/sigstore-4.1.1</li>
<li><a
href="https://github.com/docker/metadata-action/commit/025f8c5c8167edab853571a387d8e80ccc1e91ed"><code>025f8c5</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/metadata-action/commit/e98d63c3081990566e174100a3afaa97aefbbcf3"><code>e98d63c</code></a>
chore(deps): Bump semver from 7.8.1 to 7.8.5</li>
<li><a
href="https://github.com/docker/metadata-action/commit/37d93799507b94cf1c1885efd7278d52a0fb806a"><code>37d9379</code></a>
chore(deps): Bump sigstore from 4.1.0 to 4.1.1</li>
<li><a
href="https://github.com/docker/metadata-action/commit/a1b80728476a956a25c5eeaff91c4dc46e7ac1bc"><code>a1b8072</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/690">#690</a>
from docker/dependabot/npm_and_yarn/sigstore/core-3.2.1</li>
<li><a
href="https://github.com/docker/metadata-action/commit/e0e338106d6ae0da5b44537049a34620b3559a5c"><code>e0e3381</code></a>
[dependabot skip] chore: update generated content</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/metadata-action/compare/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9...dc802804100637a589fabce1cb79ff13a1411302">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/setup-buildx-action` from 4.1.0 to 4.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.0</h2>
<ul>
<li>Preserve names in esbuild bundle by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/572">docker/setup-buildx-action#572</a></li>
<li>Bump <code>@​actions/core</code> from 3.0.0 to 3.0.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/551">docker/setup-buildx-action#551</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.90.0 to 0.92.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/557">docker/setup-buildx-action#557</a>
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/580">docker/setup-buildx-action#580</a></li>
<li>Bump <code>@​sigstore/core</code> from 3.1.0 to 3.2.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/573">docker/setup-buildx-action#573</a></li>
<li>Bump <code>@​sigstore/verify</code> from 3.1.0 to 3.1.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/576">docker/setup-buildx-action#576</a></li>
<li>Bump js-yaml from 4.1.1 to 5.2.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/562">docker/setup-buildx-action#562</a></li>
<li>Bump sigstore from 4.1.0 to 4.1.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/577">docker/setup-buildx-action#577</a></li>
<li>Bump tmp from 0.2.5 to 0.2.7 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/556">docker/setup-buildx-action#556</a></li>
<li>Bump undici from 6.25.0 to 6.27.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/570">docker/setup-buildx-action#570</a></li>
<li>Bump vite from 7.3.2 to 7.3.6 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/569">docker/setup-buildx-action#569</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v4.1.0...v4.2.0">https://github.com/docker/setup-buildx-action/compare/v4.1.0...v4.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/bb05f3f5519dd87d3ba754cc423b652a5edd6d2c"><code>bb05f3f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/580">#580</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/321c814cb51fbe4af8eca00249525cc0973ea66f"><code>321c814</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/b9a36ef79ba42cfc611885a1e8c388fbf8b8cb3f"><code>b9a36ef</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.91.0 to
0.92.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/ebeab241289497cd564ac98b3cfc9e64607bb276"><code>ebeab24</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/570">#570</a>
from docker/dependabot/npm_and_yarn/undici-6.27.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/5c7b8ae78cec97a3215d4d86679b1d072eaa80cb"><code>5c7b8ae</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/037e618cd98e95e81525b15ff0e9c96f507e6a0e"><code>037e618</code></a>
build(deps): bump undici from 6.25.0 to 6.27.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/66080e5802281ec2e72b7f3108915643e702db85"><code>66080e5</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/577">#577</a>
from docker/dependabot/npm_and_yarn/sigstore-4.1.1</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/409aef0aa3f48f0a742e7dec4e0e04ab19afe93c"><code>409aef0</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/562">#562</a>
from docker/dependabot/npm_and_yarn/js-yaml-4.2.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/49c6e42949280fa0d70fb327633591be54efbfb6"><code>49c6e42</code></a>
build(deps): bump sigstore from 4.1.0 to 4.1.1</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/2211273e8121ecf9ecb7d6c7c0fcd55526d530c7"><code>2211273</code></a>
[dependabot skip] chore: update generated content</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/build-push-action` from 7.2.0 to 7.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.3.0</h2>
<ul>
<li>Preserve names in esbuild bundle by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1567">docker/build-push-action#1567</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.90.0 to 0.92.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1545">docker/build-push-action#1545</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1572">docker/build-push-action#1572</a></li>
<li>Bump <code>@​sigstore/core</code> from 3.1.0 to 3.2.1 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1568">docker/build-push-action#1568</a></li>
<li>Bump js-yaml from 4.1.1 to 4.3.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1566">docker/build-push-action#1566</a></li>
<li>Bump tmp from 0.2.5 to 0.2.7 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1547">docker/build-push-action#1547</a></li>
<li>Bump undici from 6.24.1 to 6.27.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1564">docker/build-push-action#1564</a></li>
<li>Bump vite from 7.3.2 to 7.3.6 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1563">docker/build-push-action#1563</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v7.2.0...v7.3.0">https://github.com/docker/build-push-action/compare/v7.2.0...v7.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/build-push-action/commit/53b7df96c91f9c12dcc8a07bcb9ccacbed38856a"><code>53b7df9</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1572">#1572</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/154298c1ca89be1c0e019084f0611ddca621aafc"><code>154298c</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/cb1238b9c9eb453d106b4e4142a5bd9cde710040"><code>cb1238b</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.91.0 to
0.92.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/24f845d5cbe75d2d350a984fd0e18cb7a3f29c1c"><code>24f845d</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1566">#1566</a>
from docker/dependabot/npm_and_yarn/js-yaml-4.2.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/9c6973007b52c322651c38915d5e8824cea95c50"><code>9c69730</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/bc3a3a5f72a6dca16c2c2468d1dfc55ee66d2193"><code>bc3a3a5</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1574">#1574</a>
from docker/dependabot/github_actions/aws-actions/co...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/a82c504a2387bb8bedc50072f9c554ae2a7dab5d"><code>a82c504</code></a>
chore(deps): Bump js-yaml from 4.1.1 to 4.3.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/0285a75190c039d6dac52b7711abcef3f5d8f6f6"><code>0285a75</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1573">#1573</a>
from docker/dependabot/github_actions/actions/cache-...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/c6ad2a3f9644680619de938b97c8a10a87b2a88d"><code>c6ad2a3</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1575">#1575</a>
from docker/dependabot/github_actions/actions/checko...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/d37484fb9737c5442a257e2f0ae5a8d756ed7d92"><code>d37484f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1564">#1564</a>
from docker/dependabot/npm_and_yarn/undici-6.27.0</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/build-push-action/compare/f9f3042f7e2789586610d6e8b85c8f03e5195baf...53b7df96c91f9c12dcc8a07bcb9ccacbed38856a">compare
view</a></li>
</ul>
</details>
<br />

Updates `astral-sh/setup-uv` from 8.2.0 to 8.3.2
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/11f9893b081a58869d3b5fccaea48c9e9e46f990"><code>11f9893</code></a>
chore: roll up Dependabot updates (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/948">#948</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/f79855603231e1609d02bec6956bd0e05cbc46b5"><code>f798556</code></a>
docs: update version references to v8.3.1 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/946">#946</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/e80544d808267c93733c3fd1e2c8c65e0c8707d6"><code>e80544d</code></a>
chore: update known checksums for 0.11.28 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/947">#947</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/f98e06938123ccabd21905ea5d0069192241f9f1"><code>f98e069</code></a>
Change update-docs PR labels from 'update-docs' to 'documentation' (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/945">#945</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/cd462639a967553a16241af35461402a96978d48"><code>cd46263</code></a>
chore: update known checksums for 0.11.27 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/944">#944</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/11245c7e122cd1c2297e8115d1e43fe1570f6270"><code>11245c7</code></a>
docs: update version references to v8.3.0 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/939">#939</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/d31148d669074a8d0a63714ba94f3201e7020bc3"><code>d31148d</code></a>
Strip environment markers from detected uv dependency pins (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/938">#938</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/17c398959b4611a88929fabb5c563a8e43a0ff60"><code>17c3989</code></a>
Fix cache keys for Python version ranges (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/937">#937</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/3cc3c11fdf511cab39136b7c946d973d4ad0df20"><code>3cc3c11</code></a>
chore(deps): roll up Dependabot updates (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/936">#936</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/9225f843d7a9f80a757cf25ef48901fda69ba4bc"><code>9225f84</code></a>
chore(deps): bump release-drafter/release-drafter from 7.3.1 to 7.4.0
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/924">#924</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/setup-uv/compare/fac544c07dec837d0ccb6301d7b5580bf5edae39...11f9893b081a58869d3b5fccaea48c9e9e46f990">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/setup-node` from 6.4.0 to 7.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-node/releases">actions/setup-node's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Add cache-primary-key and cache-matched-key as outputs by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1577">actions/setup-node#1577</a></li>
<li>Migrate to ESM and upgrade dependencies by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1574">actions/setup-node#1574</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Remove dummy NODE_AUTH_TOKEN export by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://redirect.github.com/actions/setup-node/pull/1558">actions/setup-node#1558</a></li>
<li>Only use <code>mirrorToken</code> in <code>getManifest</code> if
it's provided by <a
href="https://github.com/deiga"><code>@​deiga</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li>
</ul>
<h3>Documentation updates:</h3>
<ul>
<li>Add documentation for publishing to npm with Trusted Publisher
(OIDC) by <a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li>
<li>docs: Update restore-only cache documentation by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1550">actions/setup-node#1550</a></li>
<li>docs: Update caching recommendations to mitigate cache poisoning
risks by <a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1567">actions/setup-node#1567</a></li>
</ul>
<h3>Dependency update:</h3>
<ul>
<li>Upgrade <code>@​actions/cache</code> to 5.1.0, log cache write
denied by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/chiranjib-swain"><code>@​chiranjib-swain</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li>
<li><a href="https://github.com/deiga"><code>@​deiga</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li>
<li><a href="https://github.com/jasongin"><code>@​jasongin</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6...v7.0.0">https://github.com/actions/setup-node/compare/v6...v7.0.0</a></p>
<h2>v6.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update <code>@​actions/cache</code> to 5.1.0 and add security
overrides for undici and fast-xml-parser by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://redirect.github.com/actions/setup-node/pull/1579">actions/setup-node#1579</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0">https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/setup-node/commit/820762786026740c76f36085b0efc47a31fe5020"><code>8207627</code></a>
Migrate to ESM and upgrade dependencies (<a
href="https://redirect.github.com/actions/setup-node/issues/1574">#1574</a>)</li>
<li><a
href="https://github.com/actions/setup-node/commit/04be95cf3511ea51ebf9f224ddfb99cc7ab87cd4"><code>04be95c</code></a>
Add cache-primary-key and cache-matched-key as outputs (<a
href="https://redirect.github.com/actions/setup-node/issues/1577">#1577</a>)</li>
<li><a
href="https://github.com/actions/setup-node/commit/7c2c68d20d402ed6a201ada70a81341941093140"><code>7c2c68d</code></a>
docs: Update caching recommendations to mitigate cache poisoning risks
(<a
href="https://redirect.github.com/actions/setup-node/issues/1567">#1567</a>)</li>
<li><a
href="https://github.com/actions/setup-node/commit/6a61c0375d66246de94630495909f12cf8dac84d"><code>6a61c03</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/setup-node/issues/1569">#1569</a>
from jasongin/update-actions-cache-5.1.0</li>
<li><a
href="https://github.com/actions/setup-node/commit/30eb73b41ded577900c1ebf968ef95cdf8f7434f"><code>30eb73b</code></a>
Resolve high-severity audit issues</li>
<li><a
href="https://github.com/actions/setup-node/commit/4e1a87a501d0302f99e30e2748568adcb388d09f"><code>4e1a87a</code></a>
Update dist</li>
<li><a
href="https://github.com/actions/setup-node/commit/360237f0c01778d0c17291f75c56d6feae4f7574"><code>360237f</code></a>
Strict equality</li>
<li><a
href="https://github.com/actions/setup-node/commit/4f8aac5beb2f0854bc79651567a18c67eb0b9de3"><code>4f8aac5</code></a>
Bump <code>@​actions/cache</code> to 5.1.0, log cache write denied</li>
<li><a
href="https://github.com/actions/setup-node/commit/f4a67bbeca970f103397d3d2b9462cf787cd2980"><code>f4a67bb</code></a>
Only use <code>mirrorToken</code> in <code>getManifest</code> if it's
provided (<a
href="https://redirect.github.com/actions/setup-node/issues/1548">#1548</a>)</li>
<li><a
href="https://github.com/actions/setup-node/commit/0355742c943ddb13ca8a6b700f824231caa91e75"><code>0355742</code></a>
Remove dummy NODE_AUTH_TOKEN export (<a
href="https://redirect.github.com/actions/setup-node/issues/1558">#1558</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/setup-node/compare/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e...820762786026740c76f36085b0efc47a31fe5020">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action/init` from 4.36.2 to 4.37.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action/init's
releases</a>.</em></p>
<blockquote>
<h2>v4.37.0</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>v4.36.3</h2>
<p>No user facing changes.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/init's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.37.1 - 16 Jul 2026</h2>
<ul>
<li><em>Upcoming breaking change</em>: Add a deprecation warning for
customers using CodeQL version 2.20.6 and earlier. These versions of
CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise
Server 3.16, and will be unsupported by the next minor release of the
CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li>
</ul>
<h2>4.37.0 - 08 Jul 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>4.36.3 - 01 Jul 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.2 - 04 Jun 2026</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
<h2>4.36.1 - 02 Jun 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.0 - 22 May 2026</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>4.35.5 - 15 May 2026</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
<h2>4.35.4 - 07 May 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li>
</ul>
<h2>4.35.3 - 01 May 2026</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/99df26d4f13ea111d4ec1a7dddef6063f76b97e9"><code>99df26d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3996">#3996</a>
from github/update-v4.37.0-c7c896d71</li>
<li><a
href="https://github.com/github/codeql-action/commit/31c27074fda95256cda077009907f8a6022dd7c0"><code>31c2707</code></a>
Add changenote for <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a></li>
<li><a
href="https://github.com/github/codeql-action/commit/72df2181aac054d1f4b44264399d2aac12cf11c6"><code>72df218</code></a>
Update changelog for v4.37.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/c7c896d71b3055d36f2aff93b16bcc6c69923b91"><code>c7c896d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3995">#3995</a>
from github/update-bundle/codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/3f34ff0ea3f5153c96071437b7cbf71ea3757146"><code>3f34ff0</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/43bec09f1dc368b430cab4b5d69799bc904079d1"><code>43bec09</code></a>
Update default bundle to codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/f58f0d11ebf5dedd870fab2f999275f7602cfa46"><code>f58f0d1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a>
from github/mbg/repo-props/config-file-shorthands</li>
<li><a
href="https://github.com/github/codeql-action/commit/7dc37cbb5b3e37f0e1cd1f18b61e0ea849898fb8"><code>7dc37cb</code></a>
Merge remote-tracking branch 'origin/main' into
mbg/repo-props/config-file-sh...</li>
<li><a
href="https://github.com/github/codeql-action/commit/8e22350a7e28c34c82a5a499fc241923301c2c4f"><code>8e22350</code></a>
Thread <code>ActionState</code> to <code>initConfig</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/69c9e8c7d918cf2fee13b8b72fdde15883ff155b"><code>69c9e8c</code></a>
Mark some <code>status-report</code> imports as <code>type</code>-only
to avoid circular dependencies</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...99df26d4f13ea111d4ec1a7dddef6063f76b97e9">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action/autobuild` from 4.36.2 to 4.37.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action/autobuild's
releases</a>.</em></p>
<blockquote>
<h2>v4.37.0</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>v4.36.3</h2>
<p>No user facing changes.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/autobuild's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.37.1 - 16 Jul 2026</h2>
<ul>
<li><em>Upcoming breaking change</em>: Add a deprecation warning for
customers using CodeQL version 2.20.6 and earlier. These versions of
CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise
Server 3.16, and will be unsupported by the next minor release of the
CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li>
</ul>
<h2>4.37.0 - 08 Jul 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>4.36.3 - 01 Jul 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.2 - 04 Jun 2026</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
<h2>4.36.1 - 02 Jun 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.0 - 22 May 2026</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>4.35.5 - 15 May 2026</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
<h2>4.35.4 - 07 May 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li>
</ul>
<h2>4.35.3 - 01 May 2026</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/99df26d4f13ea111d4ec1a7dddef6063f76b97e9"><code>99df26d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3996">#3996</a>
from github/update-v4.37.0-c7c896d71</li>
<li><a
href="https://github.com/github/codeql-action/commit/31c27074fda95256cda077009907f8a6022dd7c0"><code>31c2707</code></a>
Add changenote for <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a></li>
<li><a
href="https://github.com/github/codeql-action/commit/72df2181aac054d1f4b44264399d2aac12cf11c6"><code>72df218</code></a>
Update changelog for v4.37.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/c7c896d71b3055d36f2aff93b16bcc6c69923b91"><code>c7c896d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3995">#3995</a>
from github/update-bundle/codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/3f34ff0ea3f5153c96071437b7cbf71ea3757146"><code>3f34ff0</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/43bec09f1dc368b430cab4b5d69799bc904079d1"><code>43bec09</code></a>
Update default bundle to codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/f58f0d11ebf5dedd870fab2f999275f7602cfa46"><code>f58f0d1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a>
from github/mbg/repo-props/config-file-shorthands</li>
<li><a
href="https://github.com/github/codeql-action/commit/7dc37cbb5b3e37f0e1cd1f18b61e0ea849898fb8"><code>7dc37cb</code></a>
Merge remote-tracking branch 'origin/main' into
mbg/repo-props/config-file-sh...</li>
<li><a
href="https://github.com/github/codeql-action/commit/8e22350a7e28c34c82a5a499fc241923301c2c4f"><code>8e22350</code></a>
Thread <code>ActionState</code> to <code>initConfig</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/69c9e8c7d918cf2fee13b8b72fdde15883ff155b"><code>69c9e8c</code></a>
Mark some <code>status-report</code> imports as <code>type</code>-only
to avoid circular dependencies</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...99df26d4f13ea111d4ec1a7dddef6063f76b97e9">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action/analyze` from 4.36.2 to 4.37.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action/analyze's
releases</a>.</em></p>
<blockquote>
<h2>v4.37.0</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>v4.36.3</h2>
<p>No user facing changes.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action/analyze's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.37.1 - 16 Jul 2026</h2>
<ul>
<li><em>Upcoming breaking change</em>: Add a deprecation warning for
customers using CodeQL version 2.20.6 and earlier. These versions of
CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise
Server 3.16, and will be unsupported by the next minor release of the
CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3956">#3956</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1">2.26.1</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/4019">#4019</a></li>
</ul>
<h2>4.37.0 - 08 Jul 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0">2.26.0</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3995">#3995</a></li>
<li>In addition to the existing input format, the
<code>config-file</code> input for the <code>codeql-action/init</code>
step will soon support a new <code>[owner/]repo[@ref][:path]</code>
format. All components except the repository name are optional. If
omitted, <code>owner</code> defaults to the same owner as the repository
the analysis is running for, <code>ref</code> to <code>main</code>, and
<code>path</code> to <code>.github/codeql-action.yaml</code>. Support
for this format ships in this version of the CodeQL Action, but will
only be enabled over the coming weeks. <a
href="https://redirect.github.com/github/codeql-action/pull/3973">#3973</a></li>
</ul>
<h2>4.36.3 - 01 Jul 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.2 - 04 Jun 2026</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
<h2>4.36.1 - 02 Jun 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.0 - 22 May 2026</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>4.35.5 - 15 May 2026</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
<h2>4.35.4 - 07 May 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li>
</ul>
<h2>4.35.3 - 01 May 2026</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/99df26d4f13ea111d4ec1a7dddef6063f76b97e9"><code>99df26d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3996">#3996</a>
from github/update-v4.37.0-c7c896d71</li>
<li><a
href="https://github.com/github/codeql-action/commit/31c27074fda95256cda077009907f8a6022dd7c0"><code>31c2707</code></a>
Add changenote for <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a></li>
<li><a
href="https://github.com/github/codeql-action/commit/72df2181aac054d1f4b44264399d2aac12cf11c6"><code>72df218</code></a>
Update changelog for v4.37.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/c7c896d71b3055d36f2aff93b16bcc6c69923b91"><code>c7c896d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3995">#3995</a>
from github/update-bundle/codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/3f34ff0ea3f5153c96071437b7cbf71ea3757146"><code>3f34ff0</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/43bec09f1dc368b430cab4b5d69799bc904079d1"><code>43bec09</code></a>
Update default bundle to codeql-bundle-v2.26.0</li>
<li><a
href="https://github.com/github/codeql-action/commit/f58f0d11ebf5dedd870fab2f999275f7602cfa46"><code>f58f0d1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3973">#3973</a>
from github/mbg/repo-props/config-file-shorthands</li>
<li><a
href="https://github.com/github/codeql-action/commit/7dc37cbb5b3e37f0e1cd1f18b61e0ea849898fb8"><code>7dc37cb</code></a>
Merge remote-tracking branch 'origin/main' into
mbg/repo-props/config-file-sh...</li>
<li><a
href="https://github.com/github/codeql-action/commit/8e22350a7e28c34c82a5a499fc241923301c2c4f"><code>8e22350</code></a>
Thread <code>ActionState</code> to <code>initConfig</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/69c9e8c7d918cf2fee13b8b72fdde15883ff155b"><code>69c9e8c</code></a>
Mark some <code>status-report</code> imports as <code>type</code>-only
to avoid circular dependencies</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...99df26d4f13ea111d4ec1a7dddef6063f76b97e9">compare
view</a></li>
</ul>
</details>
<br />

Updates `dorny/paths-filter` from 4.0.1 to 4.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/releases">dorny/paths-filter's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>fix warning message by <a
href="https://github.com/cgundy"><code>@​cgundy</code></a> in <a
href="https://redirect.github.com/dorny/paths-filter/pull/282">dorny/paths-filter#282</a></li>
<li>chore: fix GitHub spelling in logs by <a
href="https://github.com/squat"><code>@​squat</code></a> in <a
href="https://redirect.github.com/dorny/paths-filter/pull/278">dorny/paths-filter#278</a></li>
<li>fix: use rev-parse instead of branch --show-current for older git
compat by <a
href="https://github.com/saschabratton"><code>@​saschabratton</code></a>
in <a
href="https://redirect.github.com/dorny/paths-filter/pull/303">dorny/paths-filter#303</a></li>
<li>fix: work around git dubious ownership errors in container jobs by
<a
href="https://github.com/saschabratton"><code>@​saschabratton</code></a>
in <a
href="https://redirect.github.com/dorny/paths-filter/pull/317">dorny/paths-filter#317</a></li>
<li>docs: update changelog for v4.0.2 by <a
href="https://github.com/saschabratton"><code>@​saschabratton</code></a>
in <a
href="https://redirect.github.com/dorny/paths-filter/pull/318">dorny/paths-filter#318</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/cgundy"><code>@​cgundy</code></a> made
their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/282">dorny/paths-filter#282</a></li>
<li><a href="https://github.com/squat"><code>@​squat</code></a> made
their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/278">dorny/paths-filter#278</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v4.0.1...v4.0.2">https://github.com/dorny/paths-filter/compare/v4.0.1...v4.0.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md">dorny/paths-filter's
changelog</a>.</em></p>
<blockquote>
<h2>v4.0.2</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/317">Work
around git dubious ownership errors in container jobs</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/303">Use
rev-parse instead of branch --show-current for older git compat</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/282">Fix
warning message</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dorny/paths-filter/commit/7b450fff21473bca461d4b92ce414b9d0420d706"><code>7b450ff</code></a>
docs: update changelog for v4.0.2 (<a
href="https://redirect.github.com/dorny/paths-filter/issues/318">#318</a>)</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/928037783a71f24983ea250c6e55290c1b2de54f"><code>9280377</code></a>
fix: work around git dubious ownership errors in container jobs (<a
href="https://redirect.github.com/dorny/paths-filter/issues/317">#317</a>)</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/f3ceefdc7ef57bc2d8560787d4b6c33e44044cec"><code>f3ceefd</code></a>
fix: use rev-parse instead of branch --show-current for older git compat
(<a
href="https://redirect.github.com/dorny/paths-filter/issues/303">#303</a>)</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/61f87a10cd2c304679af17bb73ef192addf33c1c"><code>61f87a1</code></a>
chore: fix GitHub spelling in logs (<a
href="https://redirect.github.com/dorny/paths-filter/issues/278">#278</a>)</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/b82ff81ffbe6fb4b636bb5b47e37fd8d12b32632"><code>b82ff81</code></a>
fix warning message (<a
href="https://redirect.github.com/dorny/paths-filter/issues/282">#282</a>)</li>
<li>See full diff in <a
href="https://github.com/dorny/paths-filter/compare/v4.0.1...v4.0.2">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-19 02:51:53 -04:00
dependabot[bot] ceaccfd29f Bump prek from 0.4.8 to 0.4.9 in the python-deps group (#1116)
Bumps the python-deps group with 1 update:
[prek](https://github.com/j178/prek).

Updates `prek` from 0.4.8 to 0.4.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.9</h2>
<h2>Release Notes</h2>
<p>Released on 2026-07-11.</p>
<p>Note: This release changes the repository identity schema stored in
cached hook environments. Existing
hook environments will be invalidated, and prek will reinstall them
automatically when needed.</p>
<h3>Enhancements</h3>
<ul>
<li>Preserve additional dependency order (<a
href="https://redirect.github.com/j178/prek/pull/2311">#2311</a>)</li>
<li>Remove parallel Ruby gem installation (<a
href="https://redirect.github.com/j178/prek/pull/2307">#2307</a>)</li>
<li>Warn for missing update repositories (<a
href="https://redirect.github.com/j178/prek/pull/2316">#2316</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix mixed workspace selectors (<a
href="https://redirect.github.com/j178/prek/pull/2306">#2306</a>)</li>
<li>Fix try-repo local path resolution (<a
href="https://redirect.github.com/j178/prek/pull/2310">#2310</a>)</li>
<li>Use resolved gem executable (<a
href="https://redirect.github.com/j178/prek/pull/2308">#2308</a>)</li>
<li>Validate complete XML documents in check-xml (<a
href="https://redirect.github.com/j178/prek/pull/2312">#2312</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
<h2>Install prek 0.4.9</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://github.com/j178/prek/releases/download/v0.4.9/prek-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://github.com/j178/prek/releases/download/v0.4.9/prek-installer.ps1
| iex&quot;
</code></pre>
<h3>Install prebuilt binaries via Homebrew</h3>
<pre lang="sh"><code>brew install prek
</code></pre>
<h2>Download prek 0.4.9</h2>
<table>
<thead>
<tr>
<th>File</th>
<th>Platform</th>
<th>Checksum</th>
</tr>
</thead>
<tbody>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.9/prek-aarch64-apple-darwin.tar.gz">prek-aarch64-apple-darwin.tar.gz</a></td>
<td>Apple Silicon macOS</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.9/prek-aarch64-apple-darwin.tar.gz.sha256">checksum</a></td>
</tr>
</tbody>
</table>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.9</h2>
<p>Released on 2026-07-11.</p>
<p>Note: This release changes the repository identity schema stored in
cached hook environments. Existing
hook environments will be invalidated, and prek will reinstall them
automatically when needed.</p>
<h3>Enhancements</h3>
<ul>
<li>Preserve additional dependency order (<a
href="https://redirect.github.com/j178/prek/pull/2311">#2311</a>)</li>
<li>Remove parallel Ruby gem installation (<a
href="https://redirect.github.com/j178/prek/pull/2307">#2307</a>)</li>
<li>Warn for missing update repositories (<a
href="https://redirect.github.com/j178/prek/pull/2316">#2316</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix mixed workspace selectors (<a
href="https://redirect.github.com/j178/prek/pull/2306">#2306</a>)</li>
<li>Fix try-repo local path resolution (<a
href="https://redirect.github.com/j178/prek/pull/2310">#2310</a>)</li>
<li>Use resolved gem executable (<a
href="https://redirect.github.com/j178/prek/pull/2308">#2308</a>)</li>
<li>Validate complete XML documents in check-xml (<a
href="https://redirect.github.com/j178/prek/pull/2312">#2312</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/42b79a57f275ffe3e7fc3ad32fdf2754416779d5"><code>42b79a5</code></a>
Bump version to 0.4.9 (<a
href="https://redirect.github.com/j178/prek/issues/2318">#2318</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ecbd9dabab540d1d964a66276f70ff084c5aa14d"><code>ecbd9da</code></a>
Extract executable helpers (<a
href="https://redirect.github.com/j178/prek/issues/2317">#2317</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/25ee3c2d16086291673fed03dcc9beff09b1e03a"><code>25ee3c2</code></a>
Validate complete XML documents in check-xml (<a
href="https://redirect.github.com/j178/prek/issues/2312">#2312</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/876f7610dcc6f50dd6b85842cc5f01b36e7dc93f"><code>876f761</code></a>
Warn for missing update repositories (<a
href="https://redirect.github.com/j178/prek/issues/2316">#2316</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/61cbcbf91b0c6478afcc16a2de8fb51269c94d52"><code>61cbcbf</code></a>
Preserve additional dependency order (<a
href="https://redirect.github.com/j178/prek/issues/2311">#2311</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/4b006eba7adf4515f686647060fa852fd994359d"><code>4b006eb</code></a>
Update Rust to 1.97 (<a
href="https://redirect.github.com/j178/prek/issues/2313">#2313</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/40f6609fd824151af0cb85ca994a1cd2f6ea5d87"><code>40f6609</code></a>
Fix try-repo local path resolution (<a
href="https://redirect.github.com/j178/prek/issues/2310">#2310</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/3795e9964883a2e57ed9b783345ac1cf654160a3"><code>3795e99</code></a>
Use resolved gem executable (<a
href="https://redirect.github.com/j178/prek/issues/2308">#2308</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/de7ac64173f48f91ad746e1ebe7e8b4cd1a99d11"><code>de7ac64</code></a>
Remove parallel Ruby gem installation (<a
href="https://redirect.github.com/j178/prek/issues/2307">#2307</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/434e791453272d9badef7c5c6295342d541496ac"><code>434e791</code></a>
Fix mixed workspace selectors (<a
href="https://redirect.github.com/j178/prek/issues/2306">#2306</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.4.8...v0.4.9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prek&package-manager=uv&previous-version=0.4.8&new-version=0.4.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-15 10:28:00 -04:00
CaliBrain 6bab9989ab fix: fetch tracker .torrent links once per add and surface fetch failures (#1115)
## Summary

Fixes Prowlarr torrent downloads that fail with `Could not determine
torrent hash
from URL` when the result has no magnet link and no infohash (e.g.
MyAnonaMouse),
where fetching the .torrent from Prowlarr's proxy download link is the
only path.

Two problems compounded here:

1. **Every add attempt fetched the download link twice.**
`find_existing()`
prefetched the .torrent to compute a dedup hash, discarded the result,
and
`add_download()` fetched the same URL again seconds later. Private
tracker
links behind Prowlarr's proxy can be slow, rate-limited, or effectively
single-use, so the second hit could fail even when the link itself was
valid —
   which is why the reporter's manual fetch of the same URL succeeded.
2. **The real failure reason was invisible.** When the fetch failed
(e.g.
Prowlarr returning HTTP 500 because the tracker rejected the request —
see the
2026-07-07 MAM report on #476, which turned out to be a MAM IP-settings
problem), the reason was logged at DEBUG only and the user saw the
misleading
   generic hash error.

## What changed

- `extract_torrent_info()` now reuses a recent successful fetch of the
same URL
(short-TTL in-memory cache, successes only), so one add attempt hits the
tracker download link exactly once across `find_existing()` +
`add_download()`.
All four torrent clients (qBittorrent, Deluge, Transmission, rTorrent)
share
  this path and benefit. Failures are never cached, so retries refetch.
- `TorrentInfo` gains a `fetch_error` field. qBittorrent and rTorrent
append it
to the hash error (`... (torrent file fetch failed: 500 Server Error
...)`),
Deluge to its "Failed to fetch torrent file" error. The enriched message
still
contains the exact substring the #1109 expired-link refresh hook matches
on,
  so the refresh-and-retry path keeps working.
- Torrent fetch failures are logged at WARNING instead of DEBUG, so
non-debug
  logs show the cause.

## Validation

- `uv run pytest tests/prowlarr tests/download -q` — 498 passed
- `uv run pytest tests/newznab tests/audiobookbay -q` — 147 passed
- `uv run ruff check` / `ruff format --check` on all changed files
- New tests: fetch-cache reuse, failure-not-cached + reason capture,
expected-hash fallback on failed/hashless fetches, TTL expiry,
magnet-redirect
  reuse, and the enriched qBittorrent error message.

Fixes #1111
2026-07-14 16:21:31 -04:00
Aidan AbbottandAidan Abbott f8d3f990ca fix: Prowlarr expired download link refresh (#1109)
## Summary

Fixes Prowlarr downloads that fail after a queued torrent result’s
tracker download link expires.

Prowlarr torrent results can expose a `downloadUrl` that is only a
short-lived proxy to the upstream tracker. Some trackers, including MAM,
include expiring credentials in that URL. Shelfmark was persisting that
URL as retry data and later treating it as durable. If the in-memory
Prowlarr cache was gone, or if qBittorrent tried to add a stale URL,
Shelfmark could fail with a misleading torrent-hash error instead of
refreshing the release.

## What changed

- Stop persisting Prowlarr `downloadUrl` values as durable retry data.
- Persist only source context needed to refresh the release later.
- On a Prowlarr cache miss, re-query Prowlarr using the queued task
context.
- Accept refreshed results only when the stable identity matches the
original release:
  - `guid == task.task_id`
  - or `infoUrl == task.task_id`
- Cache the fresh raw Prowlarr result and build the download request
from its current `downloadUrl` / `magnetUrl`.
- If qBittorrent add fails with `Could not determine torrent hash from
URL`, remove the stale cached Prowlarr result, refresh once, and retry
with the fresh URL.
- Preserve existing magnet handling: torrent results continue to use
`magnetUrl` first, so the refresh path only targets Prowlarr proxy
`downloadUrl` values that can expire.
- Improve the user-facing failure when refresh cannot find the same
release:
`The indexer download link expired and the release could not be
refreshed. Search again for a fresh result.`

## Why this approach

The important constraint is avoiding accidental downloads of a different
edition or format after the original tracker link expires. Re-running a
search by title can return many plausible results, so the refresh path
deliberately requires an exact stable identity match before using any
new URL.

This treats Prowlarr `downloadUrl` as a short-lived hint, while still
allowing retries to recover when Prowlarr can find the same release
again. The one-shot retry after qBittorrent add failure handles the case
where Shelfmark still has a cached Prowlarr result, but that cached
result contains an expired proxy URL.

The refresh hook is source-specific and defaults to no-op for other
external download handlers, so Newznab and other sources keep their
existing retry behavior.

## Bug

Fixes #1012

Context:
https://github.com/calibrain/shelfmark/issues/1012#issuecomment-4917148398

## Validation

- `uv run pytest tests/prowlarr -q`
- `uv run pytest tests/download/test_orchestrator_user_output_mode.py
-q`
- `uv run pytest tests/newznab/test_handler.py
tests/audiobookbay/test_handler.py -q`
- `uv run ruff check shelfmark/core/models.py
shelfmark/download/orchestrator.py
shelfmark/download/clients/base_handler.py
shelfmark/release_sources/prowlarr/handler.py
tests/prowlarr/test_handler.py
tests/prowlarr/test_integration_handler.py
tests/prowlarr/test_failure_scenarios.py tests/prowlarr/test_source.py
tests/download/test_orchestrator_user_output_mode.py`
- after resolving conflicts with latest `main`: `uv run pytest
tests/prowlarr -q`
- after resolving conflicts with latest `main`: `uv run ruff check
shelfmark/release_sources/prowlarr/handler.py`
- after resolving conflicts with latest `main`: `uv run pytest
tests/prowlarr/test_handler.py tests/prowlarr/test_source.py -q`

Co-authored-by: Aidan Abbott <aidanabbott@Aidans-MacBook-Pro.local>
2026-07-14 14:22:29 -04:00
dependabot[bot] 30d7f228be Bump the python-deps group with 5 updates (#1114)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 14:07:49 -04:00
adman234 b291df5cc9 fix(prowlarr): prevent silent loss of indexer seed limits on transient Prowlarr API failures (#1110)
# fix(prowlarr): prevent silent loss of indexer seed limits

Related to #795, though not a fix for that specific (closed) report —
see note below.

## Problem

With "Use Prowlarr seed preferences" enabled, ~5–10% of torrent grabs
are added to the download client without their configured share limits
and seed indefinitely (∞ ETA in qBittorrent).

Seed limits are resolved once at search time.
`get_indexer_seed_settings()` builds on `get_indexers()`, which swallows
all API errors and returns `[]`. A transient failure of the
`/api/v1/indexer` call therefore produces an empty settings dict that is
indistinguishable from "no limits configured", while the search itself
(separate HTTP calls) still succeeds. Every result from that search is
cached without `configuredSeedTimeMinutes`; grabbing one sends the
torrent to the client with no limits.

Compounding factors: `cache_release()` is last-write-wins by GUID, so
one degraded search can strip enrichment from a previously good cache
entry; and the retry fields persisted at queue time snapshot the same
missing values, so retries reproduce the failure.

## Changes

- **`api.py`** — `get_indexers()` / `get_enabled_indexers_detailed()`
gain a keyword-only `raise_on_error` (default `False`, existing behavior
unchanged). `get_indexer_seed_settings()` uses it, so fetch failures now
propagate and an empty dict strictly means "nothing configured".
- **`source.py`** — searches fetch settings via
`_fetch_indexer_seed_settings()`, which maintains a module-level
last-known-good copy (merged on each success) and falls back to it with
a warning when the fetch fails. After one successful fetch, results can
no longer be cached un-enriched.
- **`handler.py`** — grab-time safety net in `_resolve_download()`: if
seed preferences are enabled, the release is a torrent, and no
configured limits are present in the cached result, the handler
re-resolves the limits from Prowlarr for that indexer
(`restrict_to=[indexerId]`) before adding to the client. If limits still
can't be resolved, a warning is logged so the condition is visible
instead of silent.
- **Tests** — regression coverage: last-known-good fallback (success
updates cache, failure falls back, failure with no history returns
empty, fallback copy is mutation-safe) and grab-time fallback (used when
enrichment is missing, tolerates Prowlarr being down, skipped when
enrichment is present). Existing test stubs for
`get_enabled_indexers_detailed` updated to accept the new kwarg.

## Testing

- `uv run pytest tests/prowlarr/test_handler.py
tests/prowlarr/test_source.py
tests/prowlarr/test_integration_handler.py` — 93 passed, 2 skipped
(Python 3.14.4)
- Full `tests/prowlarr` run has 11 pre-existing failures on this
environment (Windows path-separator assertions in the
qBittorrent/NZBGet/SABnzbd/Transmission client tests, e.g.
`/downloads/x` vs `\downloads\x`); confirmed these also fail on
unpatched `main` and are unrelated to this change
- `uv run ruff check` / `ruff format --check` — clean on touched files
- `uv run basedpyright` — 0 errors on touched files

No behavior change when `PROWLARR_USE_SEED_PREFERENCES` is disabled; the
fallback path only activates when the preference is on and enrichment is
missing for a torrent.

---

**Note on #795:** this PR references #795 for background context on the
seed-limits feature, but it does not fix that report — #795 was about
seed limits not being converted/applied at all (a units mismatch), and
was already fixed by #946 / #959. This PR fixes a separate,
still-present bug: `get_indexers()` silently swallowing transient API
errors, which intermittently drops seed limits even when the feature is
otherwise working correctly.
2026-07-09 23:25:29 -04:00
CaliBrain 9b1d4322b7 fix: resolve remaining "Could not determine torrent hash from URL" failures (#1012) (#1108) 2026-07-08 14:20:31 -04:00
dependabot[bot] d7a21ea248 Bump the python-deps group with 2 updates (#1107)
Bumps the python-deps group with 2 updates:
[apprise](https://github.com/caronc/apprise) and
[prek](https://github.com/j178/prek).

Updates `apprise` from 1.11.0 to 1.12.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/caronc/apprise/releases">apprise's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.12.0</h2>
<h2>What's Changed</h2>
<p>Apprise now supports more than 150 services! HTML -&gt; Markdown
Support now built into Apprise. But otherwise this is just a monthly
release bundling all of the bugfixes, enhancments and new services that
have accumulated since the last. <a
href="https://appriseit.com">https://appriseit.com</a> under went a few
renovations of it's own; new icons; a much improved and more useful <a
href="https://appriseit.com/url-builder/">URL Builder</a> and and
improved the search functionality on <a
href="https://appriseit.com/services/">Service List section</a>.</p>
<h3>📣 New Notification Services:</h3>
<ul>
<li>Added Stackfield support in <a
href="https://redirect.github.com/caronc/apprise/pull/1651">caronc/apprise#1651</a></li>
<li>Added PushWard Support by <a
href="https://github.com/mac-lucky"><code>@​mac-lucky</code></a> in <a
href="https://redirect.github.com/caronc/apprise/pull/1643">caronc/apprise#1643</a></li>
<li>MailerSend Support added in <a
href="https://redirect.github.com/caronc/apprise/pull/1646">caronc/apprise#1646</a></li>
<li>Added Notifyer Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1648">caronc/apprise#1648</a></li>
<li>Added support for 800.com in <a
href="https://redirect.github.com/caronc/apprise/pull/1647">caronc/apprise#1647</a></li>
<li>Added Kook Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1654">caronc/apprise#1654</a></li>
<li>Serwer SMS Support Added in <a
href="https://redirect.github.com/caronc/apprise/pull/1657">caronc/apprise#1657</a></li>
<li>Added SMSC Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1658">caronc/apprise#1658</a></li>
<li>Add Flowtriq notification service for DDoS alerting by <a
href="https://github.com/jacob-masse"><code>@​jacob-masse</code></a> in
<a
href="https://redirect.github.com/caronc/apprise/pull/1644">caronc/apprise#1644</a></li>
</ul>
<h3>🐞  Bugfixes</h3>
<ul>
<li>Fix Slack webhook botname/default identity behavior by <a
href="https://github.com/vgopalakPrgs"><code>@​vgopalakPrgs</code></a>
in <a
href="https://redirect.github.com/caronc/apprise/pull/1634">caronc/apprise#1634</a></li>
<li>Fix OneSignal url() doubling @/# target prefixes on reload by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>
in <a
href="https://redirect.github.com/caronc/apprise/pull/1649">caronc/apprise#1649</a></li>
<li>Verify SMTP TLS certificates for SMTPS and STARTTLS connections by
<a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>
in <a
href="https://redirect.github.com/caronc/apprise/pull/1640">caronc/apprise#1640</a></li>
<li>name= support fixed on http:// attachments in <a
href="https://redirect.github.com/caronc/apprise/pull/1645">caronc/apprise#1645</a></li>
</ul>
<h3>💡 Features</h3>
<ul>
<li>🔥 HTML to Markdown support in <a
href="https://redirect.github.com/caronc/apprise/pull/1638">caronc/apprise#1638</a></li>
<li>regex improvements to token parsing in <a
href="https://redirect.github.com/caronc/apprise/pull/1650">caronc/apprise#1650</a></li>
<li>Discord templating support added in <a
href="https://redirect.github.com/caronc/apprise/pull/1653">caronc/apprise#1653</a></li>
<li>support multi-attachments in single in discord message in <a
href="https://redirect.github.com/caronc/apprise/pull/1655">caronc/apprise#1655</a></li>
<li>Added RFC 2387 inline attachments to email:// in <a
href="https://redirect.github.com/caronc/apprise/pull/1659">caronc/apprise#1659</a></li>
<li>Support same-level yaml indented URL configuration entries in <a
href="https://redirect.github.com/caronc/apprise/pull/1636">caronc/apprise#1636</a></li>
<li>XMPP SASL improvments and CLI Debug output added in <a
href="https://redirect.github.com/caronc/apprise/pull/1637">caronc/apprise#1637</a></li>
<li>Support MS Teams user mentions by <a
href="https://github.com/caronc"><code>@​caronc</code></a> in <a
href="https://redirect.github.com/caronc/apprise/pull/1660">caronc/apprise#1660</a></li>
</ul>
<h3>❤️ Life-Cycle Support</h3>
<ul>
<li>removed popcorn notify plugin (no longer in service) in <a
href="https://redirect.github.com/caronc/apprise/pull/1656">caronc/apprise#1656</a></li>
<li>Update README.md to correct typo by <a
href="https://github.com/aherbert"><code>@​aherbert</code></a> in <a
href="https://redirect.github.com/caronc/apprise/pull/1642">caronc/apprise#1642</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aherbert"><code>@​aherbert</code></a>
made their first contribution in <a
href="https://redirect.github.com/caronc/apprise/pull/1642">caronc/apprise#1642</a></li>
<li><a
href="https://github.com/jacob-masse"><code>@​jacob-masse</code></a>
made their first contribution in <a
href="https://redirect.github.com/caronc/apprise/pull/1644">caronc/apprise#1644</a></li>
<li><a href="https://github.com/mac-lucky"><code>@​mac-lucky</code></a>
made their first contribution in <a
href="https://redirect.github.com/caronc/apprise/pull/1643">caronc/apprise#1643</a></li>
<li><a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>
made their first contribution in <a
href="https://redirect.github.com/caronc/apprise/pull/1640">caronc/apprise#1640</a></li>
<li><a
href="https://github.com/vgopalakPrgs"><code>@​vgopalakPrgs</code></a>
made their first contribution in <a
href="https://redirect.github.com/caronc/apprise/pull/1634">caronc/apprise#1634</a></li>
</ul>
<h2>Installation</h2>
<p>Apprise is available <a href="https://pypi.org/project/apprise/">on
PyPI</a> through <em>pip</em>:</p>
<pre lang="bash"><code># Install Apprise v1.12.0 from PyPI
pip install apprise==1.12.0
</code></pre>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/caronc/apprise/compare/v1.11.0...v1.12.0">https://github.com/caronc/apprise/compare/v1.11.0...v1.12.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/caronc/apprise/commit/c067047a3d18a81af88c7ec90d38cb1aa0fb7564"><code>c067047</code></a>
bumped version to v1.12.0</li>
<li><a
href="https://github.com/caronc/apprise/commit/183ca0c9a2f74c1c05881900409a579fa8e74a76"><code>183ca0c</code></a>
Support MS Teams user mentions (<a
href="https://redirect.github.com/caronc/apprise/issues/1660">#1660</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/493e72eada5bce551ea12aab87403d2a5c435a9b"><code>493e72e</code></a>
Added RFC 2387 inline attachments to email:// (<a
href="https://redirect.github.com/caronc/apprise/issues/1659">#1659</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/44c7ce6937385647c429cfd06bf5a441c1de6625"><code>44c7ce6</code></a>
Added SMSC Support (<a
href="https://redirect.github.com/caronc/apprise/issues/1658">#1658</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/356e0fbc58c9383e3cbe481cae8f841257ee7366"><code>356e0fb</code></a>
Serwer SMS Support Added (<a
href="https://redirect.github.com/caronc/apprise/issues/1657">#1657</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/2053e6afcd4e16ecdffce1423acf9227ba4a6b80"><code>2053e6a</code></a>
improved debug logging when upstream json response is bad</li>
<li><a
href="https://github.com/caronc/apprise/commit/8c4ecb0b8ee68b29ed2915551dccec982162b22f"><code>8c4ecb0</code></a>
Added Kook Support (<a
href="https://redirect.github.com/caronc/apprise/issues/1654">#1654</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/c98567efbc3f31cfc7281d10cc31d2fc64de4fa0"><code>c98567e</code></a>
support multi-attachments in single in discord message (<a
href="https://redirect.github.com/caronc/apprise/issues/1655">#1655</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/23782c1bff299e218d5d32bfc387ff63080e8989"><code>23782c1</code></a>
removed popcorn notify plugin (no longer in service) (<a
href="https://redirect.github.com/caronc/apprise/issues/1656">#1656</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/713a745230235161d5cf372c02d21e762f0c8def"><code>713a745</code></a>
Discord templating support added (<a
href="https://redirect.github.com/caronc/apprise/issues/1653">#1653</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/caronc/apprise/compare/v1.11.0...v1.12.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `prek` from 0.4.6 to 0.4.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.8</h2>
<h2>Release Notes</h2>
<p>Released on 2026-07-04.</p>
<h3>Enhancements</h3>
<ul>
<li>Add default_env configuration (<a
href="https://redirect.github.com/j178/prek/pull/2288">#2288</a>)</li>
<li>Rename <code>auto-update</code> to <code>update</code> (<a
href="https://redirect.github.com/j178/prek/pull/2286">#2286</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix progress collapse ordering (<a
href="https://redirect.github.com/j178/prek/pull/2291">#2291</a>)</li>
<li>Fix progress insertion after collapsed rows (<a
href="https://redirect.github.com/j178/prek/pull/2292">#2292</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
<h2>Install prek 0.4.8</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://github.com/j178/prek/releases/download/v0.4.8/prek-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://github.com/j178/prek/releases/download/v0.4.8/prek-installer.ps1
| iex&quot;
</code></pre>
<h3>Install prebuilt binaries via Homebrew</h3>
<pre lang="sh"><code>brew install prek
</code></pre>
<h2>Download prek 0.4.8</h2>
<table>
<thead>
<tr>
<th>File</th>
<th>Platform</th>
<th>Checksum</th>
</tr>
</thead>
<tbody>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-apple-darwin.tar.gz">prek-aarch64-apple-darwin.tar.gz</a></td>
<td>Apple Silicon macOS</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-apple-darwin.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-x86_64-apple-darwin.tar.gz">prek-x86_64-apple-darwin.tar.gz</a></td>
<td>Intel macOS</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-x86_64-apple-darwin.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-pc-windows-msvc.zip">prek-aarch64-pc-windows-msvc.zip</a></td>
<td>ARM64 Windows</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-i686-pc-windows-msvc.zip">prek-i686-pc-windows-msvc.zip</a></td>
<td>x86 Windows</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-i686-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-x86_64-pc-windows-msvc.zip">prek-x86_64-pc-windows-msvc.zip</a></td>
<td>x64 Windows</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-x86_64-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-unknown-linux-gnu.tar.gz">prek-aarch64-unknown-linux-gnu.tar.gz</a></td>
<td>ARM64 Linux</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-aarch64-unknown-linux-gnu.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-i686-unknown-linux-gnu.tar.gz">prek-i686-unknown-linux-gnu.tar.gz</a></td>
<td>x86 Linux</td>
<td><a
href="https://github.com/j178/prek/releases/download/v0.4.8/prek-i686-unknown-linux-gnu.tar.gz.sha256">checksum</a></td>
</tr>
</tbody>
</table>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.8</h2>
<p>Released on 2026-07-04.</p>
<h3>Enhancements</h3>
<ul>
<li>Add default_env configuration (<a
href="https://redirect.github.com/j178/prek/pull/2288">#2288</a>)</li>
<li>Rename <code>auto-update</code> to <code>update</code> (<a
href="https://redirect.github.com/j178/prek/pull/2286">#2286</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix progress collapse ordering (<a
href="https://redirect.github.com/j178/prek/pull/2291">#2291</a>)</li>
<li>Fix progress insertion after collapsed rows (<a
href="https://redirect.github.com/j178/prek/pull/2292">#2292</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/cccc61bef9310b818a27aaeed1c25ef9917b09f5"><code>cccc61b</code></a>
Bump version to 0.4.8</li>
<li><a
href="https://github.com/j178/prek/commit/1ff8e408d7024d14a7892d233a22f9ee0dc893e9"><code>1ff8e40</code></a>
Bump version to 0.4.7 (<a
href="https://redirect.github.com/j178/prek/issues/2294">#2294</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/29bfccef3e12389f00e9836c1a43b31c07787bdd"><code>29bfcce</code></a>
Add default_env configuration (<a
href="https://redirect.github.com/j178/prek/issues/2288">#2288</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/5f0e654a0ef044f6a6d8f50b075abb919818fb41"><code>5f0e654</code></a>
Fix progress insertion after collapsed rows (<a
href="https://redirect.github.com/j178/prek/issues/2292">#2292</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ce4363d33e6ade4f3f8a46902193703204ad91f8"><code>ce4363d</code></a>
Fix progress collapse ordering (<a
href="https://redirect.github.com/j178/prek/issues/2291">#2291</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/3f41d4c21593f3983dd479d21e0308e5cd602b26"><code>3f41d4c</code></a>
Remove Goldziher/kreuzberg from README (<a
href="https://redirect.github.com/j178/prek/issues/2290">#2290</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/57493f93a0eb51d2a87d334c97952d1182975a6d"><code>57493f9</code></a>
Delete <code>.github/copilot-instructions.md</code> (<a
href="https://redirect.github.com/j178/prek/issues/2287">#2287</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ec18e36cf57318d9400d56701609f0df28f106d6"><code>ec18e36</code></a>
Rename <code>auto-update</code> to <code>update</code> (<a
href="https://redirect.github.com/j178/prek/issues/2286">#2286</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/3c0e172d114e653ec67ee4b16b8e5c1b999f1428"><code>3c0e172</code></a>
Migrate to tombi for TOML formatting (<a
href="https://redirect.github.com/j178/prek/issues/2285">#2285</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/a40cd329457bc489735a34619c65c9f0bbc10fcf"><code>a40cd32</code></a>
ci: rely on setup-node npm for npm publishing (<a
href="https://redirect.github.com/j178/prek/issues/2284">#2284</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.4.6...v0.4.8">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 02:00:54 -04:00
dependabot[bot] c487c6c483 Bump seleniumbase from 4.50.4 to 4.50.5 in the python-deps group (#1106)
Bumps the python-deps group with 1 update:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase).

Updates `seleniumbase` from 4.50.4 to 4.50.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.50.5 - Fix Brave and Opera automation</h2>
<h2>Fix Brave and Opera automation</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c41948eab2d4e8a981e783042bf2f49ef4079de7">Fix
Brave Browser automation</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/2632525f3b16313cc00cd6c068cf22dfbbce7be6">Fix
Opera Browser automation</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/308e71fca644ea7a896f17e4b65d77e4c807a0f6">Refresh
Python dependencies</a></li>
</ul>
<h3>More info:</h3>
<ul>
<li>The <code>--test-type</code> arg started breaking Brave on version
150. It's no longer used if Brave is set.</li>
<li>Brave with regular Chromedriver stopped worked. Since it works with
UC, that mode is forced.</li>
<li>Opera Browser now needs specific versions of Chromedriver and UC.
(Those versions are set.)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Fix Brave and Opera automation by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4418">seleniumbase/SeleniumBase#4418</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.4...v4.50.5">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.4...v4.50.5</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/4de63c89d1815c146f675efe1ceab5f5922f7ae9"><code>4de63c8</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4418">#4418</a>
from seleniumbase/fix-brave-and-opera</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f4353ef73c5ef1de18e48f6f3380c2c777b38049"><code>f4353ef</code></a>
Version 4.50.5</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/308e71fca644ea7a896f17e4b65d77e4c807a0f6"><code>308e71f</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/2632525f3b16313cc00cd6c068cf22dfbbce7be6"><code>2632525</code></a>
Fix Opera Browser automation</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c41948eab2d4e8a981e783042bf2f49ef4079de7"><code>c41948e</code></a>
Fix Brave Browser automation</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.4...v4.50.5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=seleniumbase&package-manager=uv&previous-version=4.50.4&new-version=4.50.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-07 00:54:08 -04:00
CaliBrain 404e8cc5c5 path timeouts (#1103)
- Add configurable completed-path wait for external clients : - Add a
configurable Advanced setting, DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT,
for how long Shelfmark waits after a torrent or usenet client reports
completion before treating the completed path as missing. - Keep the
default at the existing 60-second grace period, with a maximum of 3600
seconds
- Add e2e testing
- Add e2e testing

Should fix #861
2026-07-06 01:51:58 -04:00
Alex SchittkoandCaliBrain 40d6a179b7 feat: native WireGuard VPN egress mode (USING_WIREGUARD) (#1097)
Add an opt-in WireGuard egress path alongside the existing Tor mode

---------

Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-07-06 01:51:18 -04:00
CaliBrain 02a45c1a12 fix: pin chromium to 149.0.7827.196 — Debian's 150 breaks the CDP bypasser (#1105) 2026-07-06 01:33:10 -04:00
dependabot[bot] 4c78a2f3a0 Bump the python-deps group with 2 updates (#1104)
Bumps the python-deps group with 2 updates:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase) and
[prek](https://github.com/j178/prek).

Updates `seleniumbase` from 4.50.3 to 4.50.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.50.4 - Updates for SOCKS5h support and PDF downloads</h2>
<h2>Updates for SOCKS5h support and PDF downloads</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0125a8dfa4cf8187377a68cb094bd1aa400244c0">Add
support for &quot;socks5h&quot; proxies without auth</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7c937ed4a760522ca0d546ae859c016f1e098343">Update
how PDF downloads are handled</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9ac19fbb520957429e062d952b8863210469dd3a">Update
console scripts</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0a5c44d1b6026b115c2ef257004465a21a9d6ea7">Refresh
optional Python dependencies</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a022ada3f823bd6058074ef99da47f12fd218202">Update
documentation and comments</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0b076173e998697661b8d57abaa95ee52c1b6760">Update
examples</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Updates for SOCKS5h support and PDF downloads by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4415">seleniumbase/SeleniumBase#4415</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.3...v4.50.4">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.3...v4.50.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e6a60b8f15771117811226e85920542d33bfa519"><code>e6a60b8</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4415">#4415</a>
from seleniumbase/socks5h-and-pdf-download-updates</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/17d71ef57a31a4306d2e117278e8988c47a42783"><code>17d71ef</code></a>
Version 4.50.4</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0b076173e998697661b8d57abaa95ee52c1b6760"><code>0b07617</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a022ada3f823bd6058074ef99da47f12fd218202"><code>a022ada</code></a>
Update documentation and comments</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0a5c44d1b6026b115c2ef257004465a21a9d6ea7"><code>0a5c44d</code></a>
Refresh optional Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9ac19fbb520957429e062d952b8863210469dd3a"><code>9ac19fb</code></a>
Update console scripts</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7c937ed4a760522ca0d546ae859c016f1e098343"><code>7c937ed</code></a>
Update how PDF downloads are handled</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0125a8dfa4cf8187377a68cb094bd1aa400244c0"><code>0125a8d</code></a>
Add support for &quot;socks5h&quot; proxies without auth</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.3...v4.50.4">compare
view</a></li>
</ul>
</details>
<br />

Updates `prek` from 0.4.5 to 0.4.6
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.6</h2>
<h2>Release Notes</h2>
<p>Released on 2026-07-01.</p>
<h3>Enhancements</h3>
<ul>
<li>Verify managed toolchain downloads before installation (<a
href="https://redirect.github.com/j178/prek/pull/2229">#2229</a>)</li>
<li>Add <code>PREK_DOCKER_NO_INIT</code> to opt-out Docker
<code>--init</code> (<a
href="https://redirect.github.com/j178/prek/pull/2242">#2242</a>)</li>
<li>Improve subprocess error messages (<a
href="https://redirect.github.com/j178/prek/pull/2257">#2257</a>)</li>
<li>Split run concurrency knobs: <code>PREK_CONCURRENT_HOOKS</code> and
<code>PREK_CONCURRENT_BATCHES</code> (<a
href="https://redirect.github.com/j178/prek/pull/2276">#2276</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid allocating markdown extensions per file (<a
href="https://redirect.github.com/j178/prek/pull/2245">#2245</a>)</li>
<li>Avoid unchanged config tracking writes (<a
href="https://redirect.github.com/j178/prek/pull/2247">#2247</a>)</li>
<li>Delay trailing whitespace output buffer (<a
href="https://redirect.github.com/j178/prek/pull/2244">#2244</a>)</li>
<li>Prefilter VCS permalink lines (<a
href="https://redirect.github.com/j178/prek/pull/2253">#2253</a>)</li>
<li>Skip unnecessary submodule updates during hook repo clone (<a
href="https://redirect.github.com/j178/prek/pull/2255">#2255</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Document <code>language_version</code> inferring for Python and Go
(<a
href="https://redirect.github.com/j178/prek/pull/2241">#2241</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Refactor env var handling (<a
href="https://redirect.github.com/j178/prek/pull/2277">#2277</a>)</li>
<li>Use <code>serde-saphyr</code> for YAML string quoting (<a
href="https://redirect.github.com/j178/prek/pull/2228">#2228</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/shaanmajid"><code>@​shaanmajid</code></a></li>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
<h2>Install prek 0.4.6</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://github.com/j178/prek/releases/download/v0.4.6/prek-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://github.com/j178/prek/releases/download/v0.4.6/prek-installer.ps1
| iex&quot;
</code></pre>
<h3>Install prebuilt binaries via Homebrew</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.6</h2>
<p>Released on 2026-07-01.</p>
<h3>Enhancements</h3>
<ul>
<li>Verify managed toolchain downloads before installation (<a
href="https://redirect.github.com/j178/prek/pull/2229">#2229</a>)</li>
<li>Add <code>PREK_DOCKER_NO_INIT</code> to opt-out Docker
<code>--init</code> (<a
href="https://redirect.github.com/j178/prek/pull/2242">#2242</a>)</li>
<li>Improve subprocess error messages (<a
href="https://redirect.github.com/j178/prek/pull/2257">#2257</a>)</li>
<li>Split run concurrency knobs: <code>PREK_CONCURRENT_HOOKS</code> and
<code>PREK_CONCURRENT_BATCHES</code> (<a
href="https://redirect.github.com/j178/prek/pull/2276">#2276</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid allocating markdown extensions per file (<a
href="https://redirect.github.com/j178/prek/pull/2245">#2245</a>)</li>
<li>Avoid unchanged config tracking writes (<a
href="https://redirect.github.com/j178/prek/pull/2247">#2247</a>)</li>
<li>Delay trailing whitespace output buffer (<a
href="https://redirect.github.com/j178/prek/pull/2244">#2244</a>)</li>
<li>Prefilter VCS permalink lines (<a
href="https://redirect.github.com/j178/prek/pull/2253">#2253</a>)</li>
<li>Skip unnecessary submodule updates during hook repo clone (<a
href="https://redirect.github.com/j178/prek/pull/2255">#2255</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Document <code>language_version</code> inferring for Python and Go
(<a
href="https://redirect.github.com/j178/prek/pull/2241">#2241</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Refactor env var handling (<a
href="https://redirect.github.com/j178/prek/pull/2277">#2277</a>)</li>
<li>Use <code>serde-saphyr</code> for YAML string quoting (<a
href="https://redirect.github.com/j178/prek/pull/2228">#2228</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/shaanmajid"><code>@​shaanmajid</code></a></li>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/643fba48aac2bdff4993e4d0b58c765a49df3188"><code>643fba4</code></a>
Bump version to 0.4.6 (<a
href="https://redirect.github.com/j178/prek/issues/2280">#2280</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/b0f92611f3b26c1436b98ba95678b1c95e2ac749"><code>b0f9261</code></a>
Refactor env var handling (<a
href="https://redirect.github.com/j178/prek/issues/2277">#2277</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/8494d1663e2c330e03ac0944bd6f81e8028f7a8a"><code>8494d16</code></a>
Split run concurrency knobs (<a
href="https://redirect.github.com/j178/prek/issues/2276">#2276</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/f20bbaaedaf95ebcdda053de1548b2c24e20eb55"><code>f20bbaa</code></a>
Update sample config for <code>.pre-commit-config.yaml</code> (<a
href="https://redirect.github.com/j178/prek/issues/2275">#2275</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/5485289875b75170fce1ef3ed6c8964bd48fe91c"><code>5485289</code></a>
Pin pre-commit repos to commit hash (<a
href="https://redirect.github.com/j178/prek/issues/2274">#2274</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/d418ab322bb05539409c6a90a6c898c46a6b96a1"><code>d418ab3</code></a>
Improve nix shebang parsing (<a
href="https://redirect.github.com/j178/prek/issues/2271">#2271</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/cc261c13a0a9d7e10e6a713a9d9fe81594073f75"><code>cc261c1</code></a>
Update actions/checkout action to v7 (<a
href="https://redirect.github.com/j178/prek/issues/2267">#2267</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/8d2dbba355f8cca46c6a1f2386f1505db13d6053"><code>8d2dbba</code></a>
Update Rust crate itertools to 0.15.0 (<a
href="https://redirect.github.com/j178/prek/issues/2265">#2265</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/51db86cd2ae4dd496e7a7f5ea94c5013d4e5ac1f"><code>51db86c</code></a>
Update Rust crate phf to 0.14.0 (<a
href="https://redirect.github.com/j178/prek/issues/2266">#2266</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/1aa7d389e8e9d782e11bb08a7223858557e56875"><code>1aa7d38</code></a>
Update dependency uv to v0.11.23 (<a
href="https://redirect.github.com/j178/prek/issues/2262">#2262</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.4.5...v0.4.6">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 00:32:57 -04:00
Alex Schittko 8b4230ee9f fix(bypass): resolve Xlib namespace collision breaking CDP browser startup (#1099)
## Problem

The full (browser) image ships two conflicting distributions that both
own the top-level `Xlib/` namespace:

- **`python-xlib` 0.33** (2022) — pulled by the `browser` extra
- **`python3-xlib` 0.15** (2014) — pulled transitively via `pyautogui` →
`mouseinfo`

Both install into the same `Xlib/` directory, so install order decides
which files survive. When the 2014 `python3-xlib` lands last, `Xlib.X`
is missing the `FamilyServerInterpreted` attribute that the SeleniumBase
Pure-CDP driver references during browser startup. Every bypass attempt
then fails with:

```
Pure CDP browser startup failed: module 'Xlib.X' has no attribute 'FamilyServerInterpreted'
Bypasser error: RuntimeError: Pure CDP browser startup failed: module 'Xlib.X' has no attribute 'FamilyServerInterpreted'
```

Result: **all Cloudflare / DDoS-Guard protected downloads fail** on
affected builds.

## Fix

After the browser stack is installed, uninstall the stale `python3-xlib`
and force-reinstall `python-xlib==0.33` so it deterministically owns the
namespace. A build-time assertion checks
`Xlib.X.FamilyServerInterpreted` exists so the image fails fast if the
collision ever returns.

`pyautogui` operates correctly against `python-xlib` 0.33 (superset
API), so nothing else regresses.

## Testing

- Reproduced live: a build where `python3-xlib` won produced the exact
`FamilyServerInterpreted` error on every CDP browser start; removing it
and reinstating `python-xlib==0.33` immediately restored `Chrome browser
ready (Pure CDP)` and successful `_bypass_method_cdp_solve`.
- The new build-time assertion prints `Xlib namespace OK: (0, 33)` and
exits non-zero if the attribute is ever missing.
2026-07-04 09:50:33 -04:00
dependabot[bot] b57925c39d Bump the python-deps group across 1 directory with 3 updates (#1098)
Bumps the python-deps group with 3 updates in the / directory:
[qbittorrent-api](https://github.com/rmartin16/qbittorrent-api),
[seleniumbase](https://github.com/seleniumbase/SeleniumBase) and
[basedpyright](https://github.com/detachhead/basedpyright).

Updates `qbittorrent-api` from 2026.6.0 to 2026.6.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/releases">qbittorrent-api's
releases</a>.</em></p>
<blockquote>
<h2>release-2026.6.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump the github-actions group with 4 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/629">rmartin16/qbittorrent-api#629</a></li>
<li>fix: correct copy-paste docstring error in rss_move_item by <a
href="https://github.com/AmSach"><code>@​AmSach</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/628">rmartin16/qbittorrent-api#628</a></li>
<li>Bump starlette from 1.2.1 to 1.3.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/630">rmartin16/qbittorrent-api#630</a></li>
<li>Bump cryptography from 48.0.0 to 48.0.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/631">rmartin16/qbittorrent-api#631</a></li>
<li>qBittorrent 5.2.2 support by <a
href="https://github.com/agrenott"><code>@​agrenott</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/632">rmartin16/qbittorrent-api#632</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/agrenott"><code>@​agrenott</code></a>
made their first contribution in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/632">rmartin16/qbittorrent-api#632</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.6.0...v2026.6.1">https://github.com/rmartin16/qbittorrent-api/compare/v2026.6.0...v2026.6.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md">qbittorrent-api's
changelog</a>.</em></p>
<blockquote>
<h3>v2026.6.1 (26 jun 2026)</h3>
<ul>
<li>Advertise support for qBittorrent v5.2.2</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/5985973705f7b0c4df4c5d1f7decba792973a2d5"><code>5985973</code></a>
bump to v2026.6.1</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/89c1206bcf115343d2548e5a2e61e5445c2d35bd"><code>89c1206</code></a>
qBittorrent 5.2.2 support (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/632">#632</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/491cc3003f648e6ba5e617c974fa97ce4c1316a8"><code>491cc30</code></a>
Bump cryptography from 48.0.0 to 48.0.1 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/631">#631</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/605814a55478a5f6f7b1631986787fd818a85057"><code>605814a</code></a>
Bump starlette from 1.2.1 to 1.3.1 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/630">#630</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/d1ed4487f66fe122bd8e885633d03f80892e2977"><code>d1ed448</code></a>
fix: correct copy-paste docstring error in rss_move_item (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/628">#628</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/56f3d2981d95db3323ab68edcdbe8d71e85412d9"><code>56f3d29</code></a>
Bump the github-actions group with 4 updates (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/629">#629</a>)</li>
<li>See full diff in <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.6.0...v2026.6.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.50.2 to 4.50.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.50.3 - CDP Mode: Patch 118</h2>
<h2>CDP Mode: Patch 118</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cc9050e60e1f57d7178e216182f1f6e02bdc2b16">Update
CDP Mode</a>
-- Simplifies <code>--use-chromium</code> to just
<code>--chromium</code> in command-line options
-- Use the mock-keychain when setting a custom Chromium binary location
-- Adjusts the DataDome Slider CAPTCHA-solving algorithm</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7e168b767efb81ff645a38d17097ce7c174bd6a2">Update
CDP Mode examples</a>
-- Use <code>asyncio.run()</code> instead of
<code>loop.run_until_complete()</code> as needed</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 118 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4412">seleniumbase/SeleniumBase#4412</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.2...v4.50.3">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.2...v4.50.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d2e98d47d0f3ee72464a4bb9bba0d6347ea9e34e"><code>d2e98d4</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4412">#4412</a>
from seleniumbase/cdp-mode-patch-118</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/092b0f475fb7d19ae9a5d3de16b81a0cf886adcf"><code>092b0f4</code></a>
Version 4.50.3</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f57e0662a5fd8601c75e9ab1b5eb2a51e9947c78"><code>f57e066</code></a>
Update the documentation</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7e168b767efb81ff645a38d17097ce7c174bd6a2"><code>7e168b7</code></a>
Update CDP Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cc9050e60e1f57d7178e216182f1f6e02bdc2b16"><code>cc9050e</code></a>
Update CDP Mode</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.2...v4.50.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `basedpyright` from 1.39.8 to 1.39.9
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/2802042079937529ad9f343d00a035c24e767065"><code>2802042</code></a>
fix <code>pnpm view</code> command and simplify the outcome check</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/f6e62d3550648052ebce7ccfe75e90072c2fa44a"><code>f6e62d3</code></a>
fix crash during publish</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/816614ebb5fb21303ba6df0edc299b0235e9ebf6"><code>816614e</code></a>
1.39.9</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/c79697f782786d759d2848be3994b72561863191"><code>c79697f</code></a>
remove more webpack remnants</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/2921109c27b043cda1af67521fd6b2a37373a6f6"><code>2921109</code></a>
<a
href="https://redirect.github.com/microsoft/vscode-vsce/issues/421">microsoft/vscode-vsce#421</a></li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/58120740bf2b100672830d031f23dd171b10be19"><code>5812074</code></a>
fix new test from upstream. that representation of a paramspec is wrong,
espe...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/eaaaf62a90dce1a7c275304835f5c103cd50b4c8"><code>eaaaf62</code></a>
prettier ignore new files from upstream</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/8baf13e358c905ab1a2e0395dfec40b030889e84"><code>8baf13e</code></a>
switch to pnpm because npm is the worst package manager ever made.</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/f228a802fd022367201207e062610b44bc33fd21"><code>f228a80</code></a>
fixes from merge</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/21702747ca61358441bef00e50b39451af37537d"><code>2170274</code></a>
Merge tag '1.1.411' into merge-1.1.411</li>
<li>Additional commits viewable in <a
href="https://github.com/detachhead/basedpyright/compare/v1.39.8...v1.39.9">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-04 09:47:15 -04:00
dependabot[bot] b6efed95ab Bump the gh-actions group with 2 updates (#1102)
Bumps the gh-actions group with 2 updates:
[actions/attest-build-provenance](https://github.com/actions/attest-build-provenance)
and [dorny/paths-filter](https://github.com/dorny/paths-filter).

Updates `actions/attest-build-provenance` from 4.1.0 to 4.1.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/attest-build-provenance/releases">actions/attest-build-provenance's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.1</h2>
<blockquote>
<p>[!NOTE]
As of version 4, <code>actions/attest-build-provenance</code> is simply
a wrapper on top of <a
href="https://github.com/actions/attest"><code>actions/attest</code></a>.</p>
<p>Existing applications may continue to use the
<code>attest-build-provenance</code> action, but new implementations
should use <code>actions/attest</code> instead.</p>
</blockquote>
<h2>What's Changed</h2>
<ul>
<li>Update actions/attest to v4.1.1 by <a
href="https://github.com/bdehamer"><code>@​bdehamer</code></a> in <a
href="https://redirect.github.com/actions/attest-build-provenance/pull/858">actions/attest-build-provenance#858</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/attest-build-provenance/compare/v4.1.0...v4.1.1">https://github.com/actions/attest-build-provenance/compare/v4.1.0...v4.1.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/0f67c3f4856b2e3261c31976d6725780e5e4c373"><code>0f67c3f</code></a>
Bump actions/checkout from 6.0.3 to 7.0.0 (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/857">#857</a>)</li>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/21b787db45d5d4b6fc776b99a247a6493082d1fd"><code>21b787d</code></a>
Update actions/attest to v4.1.1 (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/858">#858</a>)</li>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/f14352a605c57b0a66e0d49bba5825967f1dbedf"><code>f14352a</code></a>
add dependabot cooldown (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/851">#851</a>)</li>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/2c04a00460b64b4dfd062384e60ea87fa18e1728"><code>2c04a00</code></a>
Bump actions/checkout from 6.0.2 to 6.0.3 in the actions-minor group (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/850">#850</a>)</li>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/10334b5f1e684784025c3fc0a277c88c19089275"><code>10334b5</code></a>
remove badges from README (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/840">#840</a>)</li>
<li><a
href="https://github.com/actions/attest-build-provenance/commit/c5efebd311e9a809e832398ca2b73bb429ff3508"><code>c5efebd</code></a>
remove prober workflows (<a
href="https://redirect.github.com/actions/attest-build-provenance/issues/837">#837</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/attest-build-provenance/compare/a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32...0f67c3f4856b2e3261c31976d6725780e5e4c373">compare
view</a></li>
</ul>
</details>
<br />

Updates `dorny/paths-filter` from 4 to 4.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/releases">dorny/paths-filter's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Support merge queue by <a
href="https://github.com/masaru-iritani"><code>@​masaru-iritani</code></a>
in <a
href="https://redirect.github.com/dorny/paths-filter/pull/255">dorny/paths-filter#255</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/masaru-iritani"><code>@​masaru-iritani</code></a>
made their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/255">dorny/paths-filter#255</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v4.0.0...v4.0.1">https://github.com/dorny/paths-filter/compare/v4.0.0...v4.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md">dorny/paths-filter's
changelog</a>.</em></p>
<blockquote>
<h2>v4.0.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/255">Support
merge queue</a></li>
</ul>
<h2>v4.0.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/294">Update
action runtime to node24</a></li>
</ul>
<h2>v3.0.3</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/279">Add
missing predicate-quantifier</a></li>
</ul>
<h2>v3.0.2</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/224">Add
config parameter for predicate quantifier</a></li>
</ul>
<h2>v3.0.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/133">Compare
base and ref when token is empty</a></li>
</ul>
<h2>v3.0.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/210">Update to
Node.js 20</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/215">Update
all dependencies</a></li>
</ul>
<h2>v2.11.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/167">Update
@​actions/core to v1.10.0 - Fixes warning about deprecated
set-output</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/168">Document
need for pull-requests: read permission</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/164">Updating
to actions/checkout@v3</a></li>
</ul>
<h2>v2.11.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/157">Set
list-files input parameter as not required</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/161">Update
Node.js</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/162">Fix
incorrect handling of Unicode characters in exec()</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/163">Use
Octokit pagination</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/160">Updates
real world links</a></li>
</ul>
<h2>v2.10.2</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/91">Fix
getLocalRef() returns wrong ref</a></li>
</ul>
<h2>v2.10.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/85">Improve
robustness of change detection</a></li>
</ul>
<h2>v2.10.0</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/82">Add
ref input parameter</a></li>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/83">Fix
change detection in PR when pullRequest.changed_files is
incorrect</a></li>
</ul>
<h2>v2.9.3</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/78">Fix
change detection when base is a tag</a></li>
</ul>
<h2>v2.9.2</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/75">Fix
fetching git history</a></li>
</ul>
<h2>v2.9.1</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/74">Fix
fetching git history + fallback to unshallow repo</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dorny/paths-filter/commit/3c49e64ca26115121162fb767bc6af9e8d059f1a"><code>3c49e64</code></a>
Merge pull request <a
href="https://redirect.github.com/dorny/paths-filter/issues/210">#210</a>
from dorny/use-nodejs-20</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/8ec7be473424d724f09d3c51b7962ae5f2ffcbab"><code>8ec7be4</code></a>
Update to nodejs 20</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/100a1198b209450115509c0565d407ac269190dc"><code>100a119</code></a>
Revert back to node16</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/96be2b61c476f7b821cc2ed4eb7cbe4d96d30f60"><code>96be2b6</code></a>
Merge pull request <a
href="https://redirect.github.com/dorny/paths-filter/issues/206">#206</a>
from danielhjacobs/patch-1</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/f5071954e88595af02cdf15a1cb0c0c22fc8ca08"><code>f507195</code></a>
Update Node.js to version 20</li>
<li>See full diff in <a
href="https://github.com/dorny/paths-filter/compare/v4...v4.0.1">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-04 09:47:01 -04:00
dependabot[bot] 44a261e857 Bump the npm-deps group in /src/frontend with 9 updates (#1101)
Bumps the npm-deps group in /src/frontend with 9 updates:

| Package | From | To |
| --- | --- | --- |
|
[@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)
| `4.3.1` | `4.3.2` |
|
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)
| `7.18.0` | `7.18.1` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `26.0.0` | `26.0.1` |
|
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react)
| `6.0.2` | `6.0.3` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) |
`6.18.0` | `6.23.0` |
| [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) |
`0.56.0` | `0.57.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) |
`1.71.0` | `1.72.0` |
|
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
| `4.3.1` | `4.3.2` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.0.16` | `8.1.0` |

Updates `@tailwindcss/vite` from 4.3.1 to 4.3.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">@​tailwindcss/vite's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.2</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@​tailwindcss/vite's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.2] - 2026-06-26</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/056a1550721d4bf79ff732d5ab9414fa83f7064f"><code>056a155</code></a>
4.3.2 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20281">#20281</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/bb6a10937c7e1434db39919fbb4df4a8982dba7f"><code>bb6a109</code></a>
use <code>.ts</code> instead of <code>.css</code></li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/@tailwindcss-vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `react-router-dom` from 7.18.0 to 7.18.1
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/react-router-dom@7.18.1/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.18.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Fix incorrect <code>package.json</code> <code>main</code> field for
CommonJS builds (<a
href="https://redirect.github.com/remix-run/react-router/pull/15238">#15238</a>)</li>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.1"><code>react-router@7.18.1</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/afdf85d3c15448a41017514caca2aca038d3e9ca"><code>afdf85d</code></a>
Release v7.18.1 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15253">#15253</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/2ecaa1ddbbcd583999dda46dd5413e907e8a46f3"><code>2ecaa1d</code></a>
Fix react-router-dom main entry metadata (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15238">#15238</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.18.1/packages/react-router-dom">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 26.0.0 to 26.0.1
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitejs/plugin-react` from 6.0.2 to 6.0.3
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@​vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.0.3 (2026-06-23)</h2>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/640fd358a0e82393acfce4e92e19a6ac6e1641a7"><code>640fd35</code></a>
release: plugin-react@6.0.3</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/889efb02cdc4ec978a5e177a37e0213cfded38a4"><code>889efb0</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1249">#1249</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/6c57dd4c5d71075b48039df2532804e72880da21"><code>6c57dd4</code></a>
fix(plugin-react): use '/' base in bundledDev preamble to fix non-root
base p...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/3cc33a703636b558a1c1c99e787ddc6bd64aab2d"><code>3cc33a7</code></a>
fix(deps): update react-related dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1245">#1245</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/c0f7c7ff709dc9d88bc1f29f1b27c1b3e2bfcfca"><code>c0f7c7f</code></a>
docs: mention the Biome rule in the &quot;Consistent components
exports&quot; section (...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/cd80f0f7b2b750f6e8f719f9c3dbe4f22ddd94db"><code>cd80f0f</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1241">#1241</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/e38accafea0c7c84f7fc72fd69d9cec731fa7600"><code>e38acca</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1227">#1227</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/9a9bb26c23b966dceed47ff9ec257faeb0e777d9"><code>9a9bb26</code></a>
perf(react): improve react compiler preset so that slightly more modules
are ...</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.3/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.18.0 to 6.23.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.23.0</h2>
<ul>
<li>feat: add customCss to Starlight plugin (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1828">#1828</a>)
(f85d96f84a47f10c34df95a5246ee1ddefd95db5) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>fix: enable vite and vitest plugins when vite-plus is found (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1830">#1830</a>)
(62e97538fca8dff3d152326b114ffc4b7241a0d2) - thanks <a
href="https://github.com/ghostdevv"><code>@​ghostdevv</code></a>!</li>
<li>feat: add support for <code>@​astrojs/markdoc</code> (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1829">#1829</a>)
(94e2863308947f19f5e759cc12666952c8f683d7) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>Support nub (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1831">#1831</a>)
(8a6050e6a92da81d4875f730f852fb7d9252a018)</li>
<li>Don't report optimizeDeps and dedupe deps as unlisted (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1832">#1832</a>)
(849b5ac230e7a8c103b6e1b1e2ddb333d2da3ca0)</li>
</ul>
<h2>Release 6.22.0</h2>
<ul>
<li>Support XO v1+ (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1819">#1819</a>)
(1dffe368b5c336d190e358ab4c2e2240e3d50e26) - thanks <a
href="https://github.com/patrik-csak"><code>@​patrik-csak</code></a>!</li>
<li>feat: detect execaNode scripts in execa visitor (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1824">#1824</a>)
(5095ae1ccd0ceb083d4434e827443f03ba19a1ff) - thanks <a
href="https://github.com/gwagjiug"><code>@​gwagjiug</code></a>!</li>
<li>Skip optional peerDeps referenced only via a host (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1823">#1823</a>)
(7759a9894f2ac1d9425cf682e1e3c400f0976080)</li>
<li>docs: update npmjs.com links to npmx.dev (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1826">#1826</a>)
(11fe8bd248c839c6eeb95b06c8204c25294e0adb) - thanks <a
href="https://github.com/serhalp"><code>@​serhalp</code></a>!</li>
<li>docs: fix semi-broken link to DEVELOPMENT.md in CONTRIBUTING.md (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1827">#1827</a>)
(a5302b2466be1294633b1f40e86ca81a00605293) - thanks <a
href="https://github.com/serhalp"><code>@​serhalp</code></a>!</li>
<li>feat: add support for Lunaria (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1825">#1825</a>)
(3e1b8212086dfae26fa7f368f245285ec82af14d) - thanks <a
href="https://github.com/trueberryless"><code>@​trueberryless</code></a>!</li>
<li>Fix lint issues (76c92e2328a94257afead6ae497a747a9e2944ea)</li>
</ul>
<h2>Release 6.21.0</h2>
<ul>
<li>Detect Vite config dependencies (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1721">#1721</a>)
(8754c43368112922c6f80d1f8d1d8ddb6cb29f25)</li>
<li>fix: Update timerifyMethods to include resolveFromAST (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1814">#1814</a>)
(3c8deac3b856def31c16372f85525bf867105132) - thanks <a
href="https://github.com/gwagjiug"><code>@​gwagjiug</code></a>!</li>
<li>Fix crash on null root export in package.json (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1815">#1815</a>)
(9b8af2b343e1aacae46fedcb155252f56f9bae61)</li>
<li>Fix unresolved subpath imports with a colon prefix (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1816">#1816</a>)
(f89db4192ff7ff6c873828ed19fe40d379566b49)</li>
<li>Detect Next.js entry files in subdirectory (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1817">#1817</a>)
(f32c6ea215dde54a59af7b91fd8bdd2177cc2881)</li>
</ul>
<h2>Release 6.20.0</h2>
<ul>
<li>Add raw transfer opt-out (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1813">#1813</a>)
(6f08c680ac4acd6edf0806ba3c1c5c8f7bca24cd)</li>
<li>Fix cached plugin config cycles (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1811">#1811</a>)
(2bc2f2420ca71db1ae70846626c6152896d270ee)</li>
</ul>
<h2>Release 6.19.0</h2>
<ul>
<li>feat: support new optional sveltekit config pattern via vite config
(<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1810">#1810</a>)
(3fee8bf608e0862d7bcdd1377cfb859a9185f17d) - thanks <a
href="https://github.com/fubits1"><code>@​fubits1</code></a>!</li>
<li>Optimize hot path string scanning
(e30cfe796423e3ecd9adff42291f3c4de6604d2b)</li>
<li>Update astro snapshot
(71e71a71b888a1b8034d4438635e94831d62b330)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/a802601072b0e3c98a20b6aaea4a4c555fbd6a55"><code>a802601</code></a>
Release knip@6.23.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/849b5ac230e7a8c103b6e1b1e2ddb333d2da3ca0"><code>849b5ac</code></a>
Don't report optimizeDeps and dedupe deps as unlisted (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1832">#1832</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/8a6050e6a92da81d4875f730f852fb7d9252a018"><code>8a6050e</code></a>
Support nub (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1831">#1831</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/94e2863308947f19f5e759cc12666952c8f683d7"><code>94e2863</code></a>
feat: add support for <code>@​astrojs/markdoc</code> (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1829">#1829</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/62e97538fca8dff3d152326b114ffc4b7241a0d2"><code>62e9753</code></a>
fix: enable vite and vitest plugins when vite-plus is found (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1830">#1830</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/f85d96f84a47f10c34df95a5246ee1ddefd95db5"><code>f85d96f</code></a>
feat: add customCss to Starlight plugin (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1828">#1828</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/c0537556aa6a99ae0fa48cf743798f02dde239eb"><code>c053755</code></a>
Release knip@6.22.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/76c92e2328a94257afead6ae497a747a9e2944ea"><code>76c92e2</code></a>
Fix lint issues</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/3e1b8212086dfae26fa7f368f245285ec82af14d"><code>3e1b821</code></a>
feat: add support for Lunaria (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1825">#1825</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/11fe8bd248c839c6eeb95b06c8204c25294e0adb"><code>11fe8bd</code></a>
docs: update npmjs.com links to npmx.dev (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1826">#1826</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.23.0/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.56.0 to 0.57.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/5306f24d9e82ae36ad9c3c964f33075bc589c799"><code>5306f24</code></a>
release(apps): oxlint v1.72.0 &amp;&amp; oxfmt v0.57.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/23935">#23935</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.57.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.71.0 to 1.72.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.72.0] - 2026-06-29</h2>
<h3>🚀 Features</h3>
<ul>
<li>1c8f50c linter: Add schema for
<code>eslint/no-restricted-import</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23642">#23642</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>742be36 refactor/node/handle-callback-err: Reject invalid regex
config (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23740">#23740</a>)
(camc314)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/5306f24d9e82ae36ad9c3c964f33075bc589c799"><code>5306f24</code></a>
release(apps): oxlint v1.72.0 &amp;&amp; oxfmt v0.57.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23935">#23935</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/742be3616fc8df27053b09bdf9ff166e16761838"><code>742be36</code></a>
fix(refactor/node/handle-callback-err): reject invalid regex config (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23740">#23740</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/1c8f50c67ff636b9d8193d3d7be1511a7960f25d"><code>1c8f50c</code></a>
feat(linter): add schema for <code>eslint/no-restricted-import</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23642">#23642</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.72.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />

Updates `tailwindcss` from 4.3.1 to 4.3.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.2</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">tailwindcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.2] - 2026-06-26</h2>
<h3>Fixed</h3>
<ul>
<li>Support bare spacing values for <code>auto-rows-*</code> and
<code>auto-cols-*</code> utilities (e.g. <code>auto-rows-12</code> and
<code>auto-cols-16</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20229">#20229</a>)</li>
<li>Prevent <code>@tailwindcss/cli</code> in <code>--watch</code> mode
from crashing on Windows when <code>@source</code> points to a directory
that doesn't exist (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20242">#20242</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing in Deno v2.8.x
when <code>context.parentURL</code> is not a valid URL (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20245">#20245</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
rebuilds when the input CSS file changes in an ignored directory (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20246">#20246</a>)</li>
<li>Allow <code>@variant</code> rules used in <code>addBase(…)</code> to
use custom variants defined later (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20247">#20247</a>)</li>
<li>Prevent <code>@tailwindcss/vite</code> from crashing during HMR when
scanned files or directories are deleted (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20259">#20259</a>)</li>
<li>Generate <code>font-size</code> instead of <code>color</code>
declarations for <code>text-[--spacing(…)]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20260">#20260</a>)</li>
<li>Prevent <code>@source</code> patterns from scanning unrelated
sibling files and folders (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20263">#20263</a>)</li>
<li>Extract class candidates adjacent to Template Toolkit delimiters
like <code>%]…[%</code> in <code>.tt</code>, <code>.tt2</code>, and
<code>.tx</code> files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Extract class candidates from conditional Maud syntax like
<code>p.text-black[condition]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20269">#20269</a>)</li>
<li>Prevent <code>@position-try</code> rules from triggering unknown
at-rule warnings when optimizing CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20277">#20277</a>)</li>
<li>Support class suggestions for named opacity modifiers from
<code>--opacity</code> theme values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20287">#20287</a>)</li>
<li>Prevent type errors in <code>@tailwindcss/postcss</code> when used
with newer PostCSS patch releases (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20289">#20289</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/056a1550721d4bf79ff732d5ab9414fa83f7064f"><code>056a155</code></a>
4.3.2 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20281">#20281</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/c8b081d96376871acb0157923e894b7a929cad5b"><code>c8b081d</code></a>
Add suggestions for named opacity modifiers (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20287">#20287</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/c46f654fa0039ad4741c6ecefbe4e2a208a665c3"><code>c46f654</code></a>
Ensure <code>--alpha(…)</code> is seen as a <code>color</code>, and
<code>--spacing(…)</code> is seen as a `le...</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/5e9f66e4284164c62e80d74e69e0cbd8d9c645cc"><code>5e9f66e</code></a>
Ensure <code>@variant</code> can be used in JS based APIs (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20252">#20252</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/707c23b955bdfa7854a03195e503b95dd730b3d2"><code>707c23b</code></a>
Ensure custom variants can be used via <code>@variant</code> in
<code>addBase</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20247">#20247</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/127d17033a0518701dac8332667b12e0980870ec"><code>127d170</code></a>
Add bare value support for <code>auto-rows-*</code> and
<code>auto-cols-*</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20229">#20229</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/tailwindcss">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.0.16 to 8.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>create-vite@8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/create-vite@8.1.0/packages/create-vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>plugin-legacy@8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/plugin-legacy@8.1.0/packages/plugin-legacy/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>plugin-legacy@8.1.0-beta.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/plugin-legacy@8.1.0-beta.0/packages/plugin-legacy/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.0-beta.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.0-beta.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/vitejs/vite/compare/v8.1.0-beta.0...v8.1.0">8.1.0</a>
(2026-06-23)</h2>
<h3>Features</h3>
<ul>
<li>extend <code>server.fs.deny</code> list with common files (<a
href="https://redirect.github.com/vitejs/vite/issues/22707">#22707</a>)
(<a
href="https://github.com/vitejs/vite/commit/61ba8fdc6500e8aa668021833ae5e6ebd200466d">61ba8fd</a>)</li>
<li>update rolldown to 1.1.2 (<a
href="https://redirect.github.com/vitejs/vite/issues/22695">#22695</a>)
(<a
href="https://github.com/vitejs/vite/commit/4f008a6213014fe5e898f42561bdc621e103903e">4f008a6</a>)</li>
<li>use <code>~</code> for Rolldown (<a
href="https://redirect.github.com/vitejs/vite/issues/22693">#22693</a>)
(<a
href="https://github.com/vitejs/vite/commit/9928722f7d08de27907c48b65ddc071244166e05">9928722</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>bundled-dev:</strong> errors should be kept when incremental
build fails (<a
href="https://redirect.github.com/vitejs/vite/issues/22617">#22617</a>)
(<a
href="https://github.com/vitejs/vite/commit/9a0dd481ac2160078b8173879e0fa86e5e6af05d">9a0dd48</a>)</li>
<li>cache falsy values in perEnvironmentState (<a
href="https://redirect.github.com/vitejs/vite/issues/22715">#22715</a>)
(<a
href="https://github.com/vitejs/vite/commit/0e91e79841b501d29dc86a6b7c0313660781196a">0e91e79</a>)</li>
<li><strong>glob:</strong> respect caseSensitive option in hmr matcher
(<a
href="https://redirect.github.com/vitejs/vite/issues/22711">#22711</a>)
(<a
href="https://github.com/vitejs/vite/commit/65f525e643ba31faeaeafbc5d888b61465e6b48d">65f525e</a>)</li>
<li><strong>html:</strong> omit nonce on import map when cspNonce is
unset (<a
href="https://redirect.github.com/vitejs/vite/issues/22713">#22713</a>)
(<a
href="https://github.com/vitejs/vite/commit/8340bb51cab703427a13d5df40b0005352c1b676">8340bb5</a>)</li>
<li><strong>optimizer:</strong> skip null-valued exports in
expandGlobIds glob resolution (<a
href="https://redirect.github.com/vitejs/vite/issues/22611">#22611</a>)
(<a
href="https://github.com/vitejs/vite/commit/8b9f5cd9f19f6002e1323b10155ab943219e86aa">8b9f5cd</a>)</li>
<li>resolved build options should be kept as a getter (<a
href="https://redirect.github.com/vitejs/vite/issues/22691">#22691</a>)
(<a
href="https://github.com/vitejs/vite/commit/3527191cad6c935a3d129506cc9a893c84009037">3527191</a>)</li>
<li><strong>server:</strong> handle malformed URI in memory files
middleware (<a
href="https://redirect.github.com/vitejs/vite/issues/22714">#22714</a>)
(<a
href="https://github.com/vitejs/vite/commit/df9e0a589ff64e09c32beca9494bff4757d4ea37">df9e0a5</a>)</li>
<li>use literal envPrefix queries for Vite Task (<a
href="https://redirect.github.com/vitejs/vite/issues/22706">#22706</a>)
(<a
href="https://github.com/vitejs/vite/commit/da727337b13ac6144e523eb06852b2a52c377f22">da72733</a>)</li>
<li>warn on deprecated envFile (<a
href="https://redirect.github.com/vitejs/vite/issues/22555">#22555</a>)
(<a
href="https://github.com/vitejs/vite/commit/ed7b28352e347dc7c95d590d2e696c3e5bd1e3d7">ed7b283</a>)</li>
</ul>
<h3>Code Refactoring</h3>
<ul>
<li><strong>client:</strong> inline dev-id value in CSS selector (<a
href="https://redirect.github.com/vitejs/vite/issues/22736">#22736</a>)
(<a
href="https://github.com/vitejs/vite/commit/57f59bc843dd527a81c503684b7f408872edaef3">57f59bc</a>)</li>
<li>remove unused removeRawQuery util (<a
href="https://redirect.github.com/vitejs/vite/issues/22724">#22724</a>)
(<a
href="https://github.com/vitejs/vite/commit/403cc608e4e8633b0335f5e8221c83dfca4994f8">403cc60</a>)</li>
<li>use <code>rolldownOptions</code> property for chunkImportMap (<a
href="https://redirect.github.com/vitejs/vite/issues/22692">#22692</a>)
(<a
href="https://github.com/vitejs/vite/commit/8e8816ca9fa249d210150c5590bac06af3560aa7">8e8816c</a>)</li>
</ul>
<h2><a
href="https://github.com/vitejs/vite/compare/v8.0.16...v8.1.0-beta.0">8.1.0-beta.0</a>
(2026-06-15)</h2>
<h3>Features</h3>
<ul>
<li><code>import.meta.glob</code> support <code>caseSensitive</code>
option (<a
href="https://redirect.github.com/vitejs/vite/issues/21707">#21707</a>)
(<a
href="https://github.com/vitejs/vite/commit/2ad6737a838cc23ebb9b2766682d28b11078dab5">2ad6737</a>)</li>
<li>add warning to discourage Vite with yarn pnp (<a
href="https://redirect.github.com/vitejs/vite/issues/21906">#21906</a>)
(<a
href="https://github.com/vitejs/vite/commit/3fbb55add62a1b94a2b47b7da70db4ae99a7c943">3fbb55a</a>)</li>
<li><strong>build:</strong> chunk importmap (<a
href="https://redirect.github.com/vitejs/vite/issues/21580">#21580</a>)
(<a
href="https://github.com/vitejs/vite/commit/e1803128e5698202e22c6e5e17dc9ebd83d4f3f5">e180312</a>)</li>
<li><strong>css:</strong> support lightningcss plugin dependency (<a
href="https://redirect.github.com/vitejs/vite/issues/21748">#21748</a>)
(<a
href="https://github.com/vitejs/vite/commit/0b7aaedc98cacb00e6db33f5f79a70192da38304">0b7aaed</a>)</li>
<li><strong>deps:</strong> bump <code>@​vitejs/devtools</code> peer
dependency version (<a
href="https://redirect.github.com/vitejs/vite/issues/22542">#22542</a>)
(<a
href="https://github.com/vitejs/vite/commit/d2c2bc090bab9bb9508e5060accb5179b6310257">d2c2bc0</a>)</li>
<li><strong>html:</strong> add <code>html.additionalAssetSources</code>
option (<a
href="https://redirect.github.com/vitejs/vite/issues/21412">#21412</a>)
(<a
href="https://github.com/vitejs/vite/commit/a41404b8894d4de729ed49fb51e0b6230d6cb511">a41404b</a>)</li>
<li>integrate with Vite Task for zero-config build caching (<a
href="https://redirect.github.com/vitejs/vite/issues/22453">#22453</a>)
(<a
href="https://github.com/vitejs/vite/commit/f8d75f7723aeb635126c8dc0e0c33266c72d24c0">f8d75f7</a>)</li>
<li>rename <code>server.hmr</code> options to <code>server.ws</code>
options (<a
href="https://redirect.github.com/vitejs/vite/issues/21357">#21357</a>)
(<a
href="https://github.com/vitejs/vite/commit/9ce3036d31d4e56b8ef3730a39a7f0e54baa951f">9ce3036</a>)</li>
<li><strong>server:</strong> support multiple hosts in
__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS (<a
href="https://redirect.github.com/vitejs/vite/issues/21501">#21501</a>)
(<a
href="https://github.com/vitejs/vite/commit/735f9a19a9d0e313c865c87daad677aaf358406b">735f9a1</a>)</li>
<li>track dependencies when loading config with native (<a
href="https://redirect.github.com/vitejs/vite/issues/22602">#22602</a>)
(<a
href="https://github.com/vitejs/vite/commit/a7e2da8cdb306cfdf1660aa4b1fe24873a8dd873">a7e2da8</a>)</li>
<li><strong>types:</strong> add more precise typing for known
<code>query</code> types to match known <code>as</code> types (<a
href="https://redirect.github.com/vitejs/vite/issues/21863">#21863</a>)
(<a
href="https://github.com/vitejs/vite/commit/cc39e55401d559b771fa3e029d90c419a364b805">cc39e55</a>)</li>
<li>update rolldown to 1.1.1 (<a
href="https://redirect.github.com/vitejs/vite/issues/22593">#22593</a>)
(<a
href="https://github.com/vitejs/vite/commit/8a13d6337eea3e74d6a7abaaa7e1d378f5b9bc49">8a13d63</a>)</li>
<li><strong>wasm:</strong> direct .wasm imports (WASM ESM Integration)
(<a
href="https://redirect.github.com/vitejs/vite/issues/21779">#21779</a>)
(<a
href="https://github.com/vitejs/vite/commit/c23d85b9654685d7217cfc33817d2953b77744f8">c23d85b</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>apply correct fs restrictions for pnpm gvs (<a
href="https://redirect.github.com/vitejs/vite/issues/22415">#22415</a>)
(<a
href="https://github.com/vitejs/vite/commit/092320bfe115e4d9952a7d172bc40cd3ec14a4c3">092320b</a>)</li>
<li><strong>css:</strong> support external CSS with lightningcss (<a
href="https://redirect.github.com/vitejs/vite/issues/18389">#18389</a>)
(<a
href="https://github.com/vitejs/vite/commit/d64a1a5557b3caea9469e70b647ff2c9d9def809">d64a1a5</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22637">#22637</a>)
(<a
href="https://github.com/vitejs/vite/commit/44bb9d95a246011a2fba9a19cadeac4181bef1b4">44bb9d9</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22681">#22681</a>)
(<a
href="https://github.com/vitejs/vite/commit/f4f063382dde0d67b2158374c56443d0bf5c9501">f4f0633</a>)</li>
<li><strong>html:</strong> insert import map before modulepreload that
is not self-close tag (<a
href="https://redirect.github.com/vitejs/vite/issues/21409">#21409</a>)
(<a
href="https://github.com/vitejs/vite/commit/e399c89a7decff73ff42a4a01679ecc235ce6845">e399c89</a>)</li>
<li><strong>optimizer:</strong> preserve sourcemaps for transformed
optimized deps with follow-up transforms (<a
href="https://redirect.github.com/vitejs/vite/issues/22428">#22428</a>)
(<a
href="https://github.com/vitejs/vite/commit/1298951ebc5e5a94164c21f142fe748ca37eea68">1298951</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/5909efd8fbfd1bf1eab65427aea0613124b2797a"><code>5909efd</code></a>
fix: allow multiple <code>bindCLIShortcuts</code> calls with shortcut
merging (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21103">#21103</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/39a0a15fd24ed37257c48b795097a3794e54d255"><code>39a0a15</code></a>
chore(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21095">#21095</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/6a34ac3422686e7cf7cc9a25d299cb8e5a8d92a0"><code>6a34ac3</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21096">#21096</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/02ceaec45e17bef19159188a28d9196fed1761be"><code>02ceaec</code></a>
chore(deps): update dependency <code>@​rollup/plugin-commonjs</code> to
v29 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21099">#21099</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/572aaca4594ed2377a4f63443a449e4bf3c0468c"><code>572aaca</code></a>
release: v7.2.2</li>
<li><a
href="https://github.com/vitejs/vite/commit/728c8eeebc0ad7ba48e680f46bbdb55020b2e152"><code>728c8ee</code></a>
fix: revert &quot;refactor: use fs.cpSync (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21019">#21019</a>)&quot;
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21081">#21081</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/a532e68c6b7ed82ae7569d2d3380eb6417e9267d"><code>a532e68</code></a>
release: v7.2.1</li>
<li><a
href="https://github.com/vitejs/vite/commit/82d2d6ccf5a69c3d67e44e3704a0c3eb34db2236"><code>82d2d6c</code></a>
fix(worker): some worker asset was missing (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21074">#21074</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/f83264f5d97caa8ba80276a9ee9e82cb0e69c4ca"><code>f83264f</code></a>
refactor(build): rename <code>indexOfMatchInSlice</code> to
<code>findPreloadMarker</code> (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21054">#21054</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/8293de0e17af8a876d49761ed6651bd38b709174"><code>8293de0</code></a>
release: v7.2.0</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/create-vite@8.1.0/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-04 09:46:54 -04:00
dependabot[bot] 14bd50bfd1 Bump python from 63a4c7f to b877e50 (#1100)
Bumps python from `63a4c7f` to `b877e50`.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.14.6-slim&new-version=3.14.6-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-04 09:46:45 -04:00
dependabot[bot]andCaliBrain 4f123977ff Bump the npm-deps group in /src/frontend with 4 updates (#1091)
Bumps the npm-deps group in /src/frontend with 4 updates:
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom),
[knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip),
[oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) and
[oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint).

Updates `react-router-dom` from 7.17.0 to 7.18.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/react-router-dom@7.18.0/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.18.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.18.0"><code>react-router@7.18.0</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/6fb1e79f8304eddd8b78759edea83cb32389ebf5"><code>6fb1e79</code></a>
Release v7.18.0 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15187">#15187</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.18.0/packages/react-router-dom">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.17.0 to 6.18.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.18.0</h2>
<ul>
<li>Update dependencies (pin oxc-resolver)
(7dda4eccc65c6d61ef2546442eb752b2a73edab9)</li>
<li>Resolve tsconfig paths for non-TS importers independent of oxc
ownership (3b71565e72107d43cbd6d2ddec7ab2fbbf65c001)</li>
<li>Format (64865f8247b8956def52f1a387234562fbddd667)</li>
<li>Fix false positive for Vitest mocks (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1802">#1802</a>)
(ec93e2013deb53902b406463b30fa6386445f9c9) - thanks <a
href="https://github.com/remcohaszing"><code>@​remcohaszing</code></a>!</li>
<li>Mark npx-run binaries optional unless --no-install (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1803">#1803</a>)
(203c31e1b2bd77eb9c94f82121f353fbf0671c67)</li>
<li>Ignore pnpm [WARN] lines in ecosystem snapshots
(392835a39b9429a3d85d712025da4c6531b8ece6)</li>
<li>Update slonik snapshot
(62d802bf8d53d7790f6322f481a290e09812cbcc)</li>
<li>Update Jest entry patterns for Jest 30 (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1808">#1808</a>)
(d2caeddf32ba99ca12e5c26e891b7974392f981a) - thanks <a
href="https://github.com/gwagjiug"><code>@​gwagjiug</code></a>!</li>
<li>Report stale workspaces configuration keys as configuration hints
(<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1807">#1807</a>)
(9083c16b3313fbebf5cb3cd11cadf45ac773bc3d) - thanks <a
href="https://github.com/WooWan"><code>@​WooWan</code></a>!</li>
</ul>
<h2>Release 6.17.2</h2>
<ul>
<li>Fix up jest plugin (63dbd653b6e1be08a36401f5f728b351ab69e81b)</li>
<li>Detect coverage provider from bare <code>vitest --coverage</code>
flag (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1800">#1800</a>)
(dc11d9fc5458e6e1f734013eb82403eab07af2c1) - thanks <a
href="https://github.com/WooWan"><code>@​WooWan</code></a>!</li>
<li>Don't disable configuration hints in workspace-scoped runs (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1791">#1791</a>)
(8ce1ec8160a786dad90903e43c3ef646ffba9464) - thanks <a
href="https://github.com/WooWan"><code>@​WooWan</code></a>!</li>
<li>Detect react-email v6 packages from non-numeric version ranges
(resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1798">#1798</a>)
(27a1caeb1bff6abcccd7140c7e92e4a57197ad47)</li>
<li>Discover workspaces included after a negated pattern (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1797">#1797</a>)
(630e152f6f687d9404cc25ffa01f0d49737d9229)</li>
</ul>
<h2>Release 6.17.1</h2>
<ul>
<li>Remove ignoreBinaries w/ tar
(b13d0ca1ce0a201b7e66f725039d9f346b4d424e)</li>
<li>Wrap up docs/refs (29f3e46cc765a70643bcf2ef96e940ff371f39c6)</li>
<li>Update dependencies (7b2f3458176110900204fa49e50650ac50d1f4db)</li>
<li>Fix up vscode-languageclient imports
(820c2335ca63f329f862eb8ec5c264bd8d5f09eb)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/7bfd556b0217f3ee09fd953132bdef860417c44c"><code>7bfd556</code></a>
Release knip@6.18.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/9083c16b3313fbebf5cb3cd11cadf45ac773bc3d"><code>9083c16</code></a>
Report stale workspaces configuration keys as configuration hints (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1807">#1807</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/d2caeddf32ba99ca12e5c26e891b7974392f981a"><code>d2caedd</code></a>
Update Jest entry patterns for Jest 30 (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1808">#1808</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/203c31e1b2bd77eb9c94f82121f353fbf0671c67"><code>203c31e</code></a>
Mark npx-run binaries optional unless --no-install (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1803">#1803</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/ec93e2013deb53902b406463b30fa6386445f9c9"><code>ec93e20</code></a>
Fix false positive for Vitest mocks (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1802">#1802</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/64865f8247b8956def52f1a387234562fbddd667"><code>64865f8</code></a>
Format</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/3b71565e72107d43cbd6d2ddec7ab2fbbf65c001"><code>3b71565</code></a>
Resolve tsconfig paths for non-TS importers independent of oxc
ownership</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/7dda4eccc65c6d61ef2546442eb752b2a73edab9"><code>7dda4ec</code></a>
Update dependencies (pin oxc-resolver)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/419805396c10579b51a2576fe70971910ad58b55"><code>4198053</code></a>
Release knip@6.17.2</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/630e152f6f687d9404cc25ffa01f0d49737d9229"><code>630e152</code></a>
Discover workspaces included after a negated pattern (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1797">#1797</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.18.0/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.55.0 to 0.56.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxfmt/CHANGELOG.md">oxfmt's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this package will be documented in this
file.</p>
<p>The format is based on <a
href="https://keepachangelog.com/en/1.0.0">Keep a Changelog</a>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/c4be770f24adc4026efa96fb82182f743c55e423"><code>c4be770</code></a>
release(apps): oxlint v1.71.0 &amp;&amp; oxfmt v0.56.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/23707">#23707</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.56.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.70.0 to 1.71.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.71.0] - 2026-06-22</h2>
<h3>🚀 Features</h3>
<ul>
<li>0dc2405 linter: Add schema for
<code>eslint/no-restricted-properties</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23619">#23619</a>)
(Sysix)</li>
<li>b638d0e linter: Add schema for <code>node/callback-return</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23615">#23615</a>)
(Sysix)</li>
<li>eb8bedc linter: Add schema for <code>import/extensions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23557">#23557</a>)
(WaterWhisperer)</li>
<li>46f3625 linter: Implement node/no-sync rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23589">#23589</a>)
(fujitani sora)</li>
<li>b01739a linter: Add schema for
<code>unicorn/numeric-separators-style</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23554">#23554</a>)
(Mikhail Baev)</li>
<li>68afd2a linter/node: Implement <code>no-mixed-requires</code> rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23539">#23539</a>)
(fujitani sora)</li>
<li>a421215 linter: Add schema for
<code>eslint/prefer-destructuring</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23410">#23410</a>)
(WaterWhisperer)</li>
<li>84438be linter/jsdoc: Added missing options to
<code>require-param-description</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23416">#23416</a>)
(kapobajza)</li>
<li>51910df linter/jsdoc: Add missing options to
<code>require-param-type</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23418">#23418</a>)
(kapobajza)</li>
<li>e90925f linter/unicorn: Implement prefer-number-coercion rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23497">#23497</a>)
(Shekhu☺️)</li>
<li>dd1c866 linter/vue: Implement no-async-in-computed-properties rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23493">#23493</a>)
(bab)</li>
<li>b02444e linter: Add schema for <code>react/jsx-no-script-url</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23475">#23475</a>)
(WaterWhisperer)</li>
<li>a8dce46 linter/unicorn: Implement <code>max-nested-calls</code> rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23461">#23461</a>)
(arieleli01212)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>a303c23 linter/jsx-a11y: Align <code>anchor-is-valid</code> config
with upstream (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23446">#23446</a>)
(camc314)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>b50bf4d linter: Remove manually written options doc for
<code>eslint/arrow-body-style</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23490">#23490</a>)
(Mikhail Baev)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/c4be770f24adc4026efa96fb82182f743c55e423"><code>c4be770</code></a>
release(apps): oxlint v1.71.0 &amp;&amp; oxfmt v0.56.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23707">#23707</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/0dc24054119b22247c6a7b9bdb20cc6e589f267a"><code>0dc2405</code></a>
feat(linter): add schema for
<code>eslint/no-restricted-properties</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23619">#23619</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/b638d0ee1df63487e7c04e031b4b71ab10d592ce"><code>b638d0e</code></a>
feat(linter): add schema for <code>node/callback-return</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23615">#23615</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/6d355ab8b3644505c4491da5fc4ec88695de50f7"><code>6d355ab</code></a>
refactor(linter): remove <code>number_as_object_schema</code> helper (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23614">#23614</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/eb8bedc2fba9cead8632a75bb7936205fae7dcf0"><code>eb8bedc</code></a>
feat(linter): add schema for <code>import/extensions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23557">#23557</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/46f362530da1c2c5e868613e339999314b9f3a72"><code>46f3625</code></a>
feat(linter): implement node/no-sync rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23589">#23589</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/953c7b3f1c9e2c80ee1b782f1540d277cc22ed99"><code>953c7b3</code></a>
refactor(linter): make <code>unicorn/numeric-separators-style</code>
options <code>u32</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23558">#23558</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/b01739ade376a9862fdb325ac9ef7023f504baf3"><code>b01739a</code></a>
feat(linter): add schema for
<code>unicorn/numeric-separators-style</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23554">#23554</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/68afd2a1f7c8d624b17c0e24880f684d3c7db3c5"><code>68afd2a</code></a>
feat(linter/node): implement <code>no-mixed-requires</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23539">#23539</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/b08e9f5b9e9d948f873d199fb6317997cd296e11"><code>b08e9f5</code></a>
refactor(linter): re-enable schema for
`jsx_a11y/no-noninteractive-element-in...</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.71.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-29 12:23:35 -04:00
dependabot[bot] e3b05d6030 Bump the python-deps group with 3 updates (#1094)
Bumps the python-deps group with 3 updates:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase),
[pytest](https://github.com/pytest-dev/pytest) and
[ruff](https://github.com/astral-sh/ruff).

Updates `seleniumbase` from 4.50.1 to 4.50.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.50.2 - CDP Mode: Patch 117</h2>
<h2>CDP Mode: Patch 117</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/89858eaffdabcacec77b5357a60418b7a8e59c5e">Optimize
CDP Mode</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e32858d3b6f0262570ffc81c13a387bd5f74865c">Update
Dashboard layout</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/12450caa378317d2673a8b375474c11959f21682">Update
CDP Mode examples</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f2e9878ca10ba849221b0905023ed373990cfaf1">Refresh
Python dependencies</a></li>
</ul>
<p>This includes several improvements to CDP Mode:</p>
<ul>
<li>Fixes a bug where temporary user_data_dirs wasn't getting cleaned up
properly.</li>
<li>Fewer asyncio event loops used for browser processes. (Same one for
startup and usage.)</li>
<li>The painted <code>flash()</code> dot is no longer used everywhere
automatically. (Anti-bots started detecting it.)</li>
</ul>
<p>Other updates include:</p>
<ul>
<li>Refreshed Python dependencies.</li>
<li>A small change to Dashboard layout.</li>
<li>Updated examples due to website changes.</li>
</ul>
<p>Special thanks to <a
href="https://github.com/montovaneli"><code>@​montovaneli</code></a>.
(<a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4408">seleniumbase/SeleniumBase#4408</a>)</p>
<p>Changes are expected in version <code>4.50.2</code>.</p>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 117 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4409">seleniumbase/SeleniumBase#4409</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.1...v4.50.2">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.1...v4.50.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/08a5e1b3bb7869425285453263e286a505111206"><code>08a5e1b</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4409">#4409</a>
from seleniumbase/cdp-mode-patch-117</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e2fd3edce00bf7f38ef6ce0ce85322fe114ef5f6"><code>e2fd3ed</code></a>
Version 4.50.2</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f2e9878ca10ba849221b0905023ed373990cfaf1"><code>f2e9878</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/12450caa378317d2673a8b375474c11959f21682"><code>12450ca</code></a>
Update CDP Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e32858d3b6f0262570ffc81c13a387bd5f74865c"><code>e32858d</code></a>
Update Dashboard layout</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/89858eaffdabcacec77b5357a60418b7a8e59c5e"><code>89858ea</code></a>
Optimize CDP Mode</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.1...v4.50.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `pytest` from 9.1.0 to 9.1.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pytest-dev/pytest/releases">pytest's
releases</a>.</em></p>
<blockquote>
<h2>9.1.1</h2>
<h1>pytest 9.1.1 (2026-06-19)</h1>
<h2>Bug fixes</h2>
<ul>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14220">#14220</a>:
Fixed a logic bug in <code>pytest.RaisesGroup</code> which would might
cause it to display incorrect &quot;It matches <!-- raw HTML omitted
-->FooError()<!-- raw HTML omitted --> which was paired with <!-- raw
HTML omitted -->BarError<!-- raw HTML omitted -->&quot; messages.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14591">#14591</a>:
Fixed a regression in pytest 9.1.0 which caused overriding a
parametrized fixture with an indirect <!-- raw HTML omitted --><a
href="https://github.com/pytest"><code>@​pytest</code></a>.mark.parametrize<!--
raw HTML omitted --> to fail with &quot;duplicate parametrization of
'&lt;fixture name&gt;'&quot;.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14606">#14606</a>:
Fixed <code>list-item</code> typing errors from mypy in
<code>@pytest.mark.parametrize &lt;pytest.mark.parametrize
ref&gt;</code> <code>argvalues</code> parameter.</li>
<li><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14608">#14608</a>:
Fixed a regression in pytest 9.1.0 where <code>conftest.py</code> files
located in <code>&lt;invocation dir&gt;/test*</code> were no longer
loaded as initial conftests when invoked without arguments.
This could cause certain hooks (like <code>pytest_addoption</code>) in
these files to not fire.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pytest-dev/pytest/commit/cf470ec0bf7eb89cd97dd56df4859eae5db46447"><code>cf470ec</code></a>
Prepare release version 9.1.1</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/e0c8ce6cc5db1f08363be6f152c32e6838df2690"><code>e0c8ce6</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14625">#14625</a>
from pytest-dev/patchback/backports/9.1.x/a07c31a97...</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/1b82d1694fce22385ee7a4287917fbafbaf2e757"><code>1b82d16</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14624">#14624</a>
from pytest-dev/patchback/backports/9.1.x/b375b79ec...</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/501c4bc784da3b08bfcaa64858eba5d15dc59e53"><code>501c4bc</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14596">#14596</a>
from bluetech/doc-classmethod</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/b61f588e36e9377c3d1d3f06bece1da0fc31d9ca"><code>b61f588</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14622">#14622</a>
from chrisburr/fix-14608-initial-conftest-test-subdir</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/9a567e009f4d2da3ce1721c6db3109cb5744d40a"><code>9a567e0</code></a>
[automated] Update plugin list (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14617">#14617</a>)
(<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14618">#14618</a>)</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/ef8b2993e5b48639e4a3d97d0525df9760781384"><code>ef8b299</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14620">#14620</a>
from pytest-dev/patchback/backports/9.1.x/680f9f3ed...</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/66abd0784d4cb7c1ba44ab9a8896506cd4985acc"><code>66abd07</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14220">#14220</a>
from bysiber/fix-stale-iexp-raisesgroup</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/79fbf93b666cac5f27c9dad047943d47b766c8d5"><code>79fbf93</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14612">#14612</a>
from pytest-dev/patchback/backports/9.1.x/974ed48b6...</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/0d312eb876177e9f1c04262b54060a41034ebf5c"><code>0d312eb</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14611">#14611</a>
from bluetech/parametrize-argvalues-typing</li>
<li>Additional commits viewable in <a
href="https://github.com/pytest-dev/pytest/compare/9.1.0...9.1.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `ruff` from 0.15.18 to 0.15.20
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.20</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-25.</p>
<h3>Preview features</h3>
<ul>
<li>Allow human-readable names in rule selectors (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25887">#25887</a>)</li>
<li>Emit a warning instead of an error for unknown rule selectors (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26113">#26113</a>)</li>
<li>Match <code>noqa</code> shebang handling in <code>ruff:ignore</code>
comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26286">#26286</a>)</li>
<li>[<code>ruff</code>] Remove <code>pytest-fixture-autouse</code>
(<code>RUF076</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26240">#26240</a>,
<a
href="https://redirect.github.com/astral-sh/ruff/pull/26371">#26371</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Add versioning sections to custom crate READMEs (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26317">#26317</a>)</li>
<li>Update <code>ruff_python_parser</code> README for crates.io (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26315">#26315</a>)</li>
<li>[<code>perflint</code>] Clarify that <code>PERF402</code> applies to
any iterable (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26242">#26242</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/dhruvmanila"><code>@​dhruvmanila</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/trilamsr"><code>@​trilamsr</code></a></li>
</ul>
<h2>Install ruff 0.15.20</h2>
<h3>Install prebuilt binaries via shell script</h3>
<pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-installer.sh
| sh
</code></pre>
<h3>Install prebuilt binaries via powershell script</h3>
<pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-installer.ps1
| iex&quot;
</code></pre>
<h2>Download ruff 0.15.20</h2>
<table>
<thead>
<tr>
<th>File</th>
<th>Platform</th>
<th>Checksum</th>
</tr>
</thead>
<tbody>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-apple-darwin.tar.gz">ruff-aarch64-apple-darwin.tar.gz</a></td>
<td>Apple Silicon macOS</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-apple-darwin.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-x86_64-apple-darwin.tar.gz">ruff-x86_64-apple-darwin.tar.gz</a></td>
<td>Intel macOS</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-x86_64-apple-darwin.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-pc-windows-msvc.zip">ruff-aarch64-pc-windows-msvc.zip</a></td>
<td>ARM64 Windows</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-i686-pc-windows-msvc.zip">ruff-i686-pc-windows-msvc.zip</a></td>
<td>x86 Windows</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-i686-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-x86_64-pc-windows-msvc.zip">ruff-x86_64-pc-windows-msvc.zip</a></td>
<td>x64 Windows</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-x86_64-pc-windows-msvc.zip.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-unknown-linux-gnu.tar.gz">ruff-aarch64-unknown-linux-gnu.tar.gz</a></td>
<td>ARM64 Linux</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-aarch64-unknown-linux-gnu.tar.gz.sha256">checksum</a></td>
</tr>
<tr>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-i686-unknown-linux-gnu.tar.gz">ruff-i686-unknown-linux-gnu.tar.gz</a></td>
<td>x86 Linux</td>
<td><a
href="https://releases.astral.sh/github/ruff/releases/download/0.15.20/ruff-i686-unknown-linux-gnu.tar.gz.sha256">checksum</a></td>
</tr>
</tbody>
</table>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.20</h2>
<p>Released on 2026-06-25.</p>
<h3>Preview features</h3>
<ul>
<li>Allow human-readable names in rule selectors (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25887">#25887</a>)</li>
<li>Emit a warning instead of an error for unknown rule selectors (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26113">#26113</a>)</li>
<li>Match <code>noqa</code> shebang handling in <code>ruff:ignore</code>
comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26286">#26286</a>)</li>
<li>[<code>ruff</code>] Remove <code>pytest-fixture-autouse</code>
(<code>RUF076</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26240">#26240</a>,
<a
href="https://redirect.github.com/astral-sh/ruff/pull/26371">#26371</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Add versioning sections to custom crate READMEs (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26317">#26317</a>)</li>
<li>Update <code>ruff_python_parser</code> README for crates.io (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26315">#26315</a>)</li>
<li>[<code>perflint</code>] Clarify that <code>PERF402</code> applies to
any iterable (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26242">#26242</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/dhruvmanila"><code>@​dhruvmanila</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/trilamsr"><code>@​trilamsr</code></a></li>
</ul>
<h2>0.15.19</h2>
<p>Released on 2026-06-23.</p>
<h3>Preview features</h3>
<ul>
<li>Support human-readable names when hovering suppression comments and
in code actions (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26114">#26114</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fall back to default settings when editor-only settings are invalid
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/26244">#26244</a>)</li>
<li>Fix panic when inserting text at a notebook cell boundary (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26111">#26111</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>pylint</code>] Update fix suggestions for
<code>__floor__</code>, <code>__trunc__</code>,
<code>__length_hint__</code>, and <code>__matmul__</code> variants
(<code>PLC2801</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26239">#26239</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid allocating when parsing single string literals (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26200">#26200</a>)</li>
<li>Avoid reallocating singleton call arguments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26223">#26223</a>)</li>
<li>Lazily create source files for lint diagnostics (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26226">#26226</a>)</li>
<li>Optimize formatter text width and indentation (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26236">#26236</a>)</li>
<li>Reserve capacity for builtin bindings (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26229">#26229</a>)</li>
<li>Skip repeated-key checks for singleton dictionaries (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26228">#26228</a>)</li>
<li>Use ArrayVec for qualified name segments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26224">#26224</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/ruff/commit/f82a36b6baf8c0547a17bbde6c0d927ccd45d938"><code>f82a36b</code></a>
Bump 0.15.20 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26376">#26376</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/af329438b55d5aa8ca28725f17abbae63b5c815d"><code>af32943</code></a>
Improve the summarise-ecosystem-results skill (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26378">#26378</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/485ebab5de692aad34720898cd80245b6092ba86"><code>485ebab</code></a>
Remove <code>RUF076</code> name from schema (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26371">#26371</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/ef81835ce3da615346584dc446de0fe26bfc154b"><code>ef81835</code></a>
[ty] Implement rust-analyzer's &quot;Click for full compiler
diagnostic&quot; feature (...</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/572b31e2377a701a7365f069f6ef87002962cb2b"><code>572b31e</code></a>
[<code>ruff</code>] Remove <code>pytest-fixture-autouse</code>
(<code>RUF076</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26240">#26240</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/f703f219d7fddd1a4abba9fa81e34773c185a4b9"><code>f703f21</code></a>
Allow human-readable names in rule selectors (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25887">#25887</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/0d726b28ee35413926145ffef4ac1143cae9ea1e"><code>0d726b2</code></a>
[ty] Reuse equality semantics for membership compatibility (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25955">#25955</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/dbe6e9848c3f78fdaf543cfc000939ebc73b5f00"><code>dbe6e98</code></a>
[ty] Infer definite equality comparison results (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26337">#26337</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/e700ea357a2196d76b58eb89b2031ddb5ca896e0"><code>e700ea3</code></a>
[ty] Prove TypedDict structural patterns exhaustive (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26285">#26285</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/6a0d2ec93959d966430b8c39d4de5c3e8a88e911"><code>6a0d2ec</code></a>
[ty] Widen inferred class-valued instance attributes (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26338">#26338</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.15.18...0.15.20">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-29 12:23:19 -04:00
dependabot[bot] 995d8d6631 Bump @types/node from 25.9.3 to 26.0.0 in /src/frontend (#1092)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 25.9.3 to 26.0.0.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=25.9.3&new-version=26.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 14:54:15 -04:00
dependabot[bot] 9a27334d9c Bump the gh-actions group with 2 updates (#1093)
Bumps the gh-actions group with 2 updates:
[actions/checkout](https://github.com/actions/checkout) and
[dorny/paths-filter](https://github.com/dorny/paths-filter).

Updates `actions/checkout` from 4 to 7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>block checking out fork pr for pull_request_target and workflow_run
by <a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
<li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the
minor-actions-dependencies group across 1 directory by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li>
<li>Bump flatted from 3.3.1 to 3.4.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li>
<li>Bump js-yaml from 4.1.0 to 4.2.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li>
<li>Bump <code>@​actions/core</code> and
<code>@​actions/tool-cache</code> and Remove uuid by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li>
<li>upgrade module to esm and update dependencies by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li>
<li>Bump the minor-npm-dependencies group across 1 directory with 3
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li>
<li>getting ready for checkout v7 release by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li>
<li>update error wording by <a
href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aiqiaoy"><code>@​aiqiaoy</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p>
<h2>v6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update changelog by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>Update changelog for v6.0.3 by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yaananth"><code>@​yaananth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p>
<h2>v6.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID
is set by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2355">actions/checkout#2355</a></li>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6.0.1...v6.0.2">https://github.com/actions/checkout/compare/v6.0.1...v6.0.2</a></p>
<h2>v6.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update all references from v5 and v4 to v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
<li>Clarify v6 README by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>v6-beta by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a>
update error wording (<a
href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a>
getting ready for checkout v7 release (<a
href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a>
Bump the minor-npm-dependencies group across 1 directory with 3 updates
(<a
href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a>
upgrade module to esm and update dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a>
Bump <code>@​actions/core</code> and <code>@​actions/tool-cache</code>
and Remove uuid (<a
href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a>
Bump js-yaml from 4.1.0 to 4.2.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a>
Bump flatted from 3.3.1 to 3.4.2 (<a
href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a>
Bump actions/publish-immutable-action (<a
href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a>
block checking out fork pr for pull_request_target and workflow_run (<a
href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a>
Update changelog for v6.0.3 (<a
href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/checkout/compare/v4...v7">compare
view</a></li>
</ul>
</details>
<br />

Updates `dorny/paths-filter` from 3 to 4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/releases">dorny/paths-filter's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: update action runtime to node24 by <a
href="https://github.com/saschabratton"><code>@​saschabratton</code></a>
in <a
href="https://redirect.github.com/dorny/paths-filter/pull/294">dorny/paths-filter#294</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/saschabratton"><code>@​saschabratton</code></a>
made their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/294">dorny/paths-filter#294</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v3.0.3...v4.0.0">https://github.com/dorny/paths-filter/compare/v3.0.3...v4.0.0</a></p>
<h2>v3.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Add missing predicate-quantifier by <a
href="https://github.com/wardpeet"><code>@​wardpeet</code></a> in <a
href="https://redirect.github.com/dorny/paths-filter/pull/279">dorny/paths-filter#279</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/wardpeet"><code>@​wardpeet</code></a>
made their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/279">dorny/paths-filter#279</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v3...v3.0.3">https://github.com/dorny/paths-filter/compare/v3...v3.0.3</a></p>
<h2>v3.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add config parameter for predicate quantifier by <a
href="https://github.com/petermetz"><code>@​petermetz</code></a> in <a
href="https://redirect.github.com/dorny/paths-filter/pull/224">dorny/paths-filter#224</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/petermetz"><code>@​petermetz</code></a>
made their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/224">dorny/paths-filter#224</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v3...v3.0.2">https://github.com/dorny/paths-filter/compare/v3...v3.0.2</a></p>
<h2>v3.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Compare base and ref when token is empty by <a
href="https://github.com/frouioui"><code>@​frouioui</code></a> in <a
href="https://redirect.github.com/dorny/paths-filter/pull/133">dorny/paths-filter#133</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/frouioui"><code>@​frouioui</code></a>
made their first contribution in <a
href="https://redirect.github.com/dorny/paths-filter/pull/133">dorny/paths-filter#133</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dorny/paths-filter/compare/v3...v3.0.1">https://github.com/dorny/paths-filter/compare/v3...v3.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md">dorny/paths-filter's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v4.0.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/294">Update
action runtime to node24</a></li>
</ul>
<h2>v3.0.3</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/279">Add
missing predicate-quantifier</a></li>
</ul>
<h2>v3.0.2</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/224">Add
config parameter for predicate quantifier</a></li>
</ul>
<h2>v3.0.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/133">Compare
base and ref when token is empty</a></li>
</ul>
<h2>v3.0.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/210">Update to
Node.js 20</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/215">Update
all dependencies</a></li>
</ul>
<h2>v2.11.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/167">Update
@​actions/core to v1.10.0 - Fixes warning about deprecated
set-output</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/168">Document
need for pull-requests: read permission</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/164">Updating
to actions/checkout@v3</a></li>
</ul>
<h2>v2.11.0</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/157">Set
list-files input parameter as not required</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/161">Update
Node.js</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/162">Fix
incorrect handling of Unicode characters in exec()</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/163">Use
Octokit pagination</a></li>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/160">Updates
real world links</a></li>
</ul>
<h2>v2.10.2</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/91">Fix
getLocalRef() returns wrong ref</a></li>
</ul>
<h2>v2.10.1</h2>
<ul>
<li><a
href="https://redirect.github.com/dorny/paths-filter/pull/85">Improve
robustness of change detection</a></li>
</ul>
<h2>v2.10.0</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/82">Add
ref input parameter</a></li>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/83">Fix
change detection in PR when pullRequest.changed_files is
incorrect</a></li>
</ul>
<h2>v2.9.3</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/78">Fix
change detection when base is a tag</a></li>
</ul>
<h2>v2.9.2</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/75">Fix
fetching git history</a></li>
</ul>
<h2>v2.9.1</h2>
<ul>
<li><a href="https://redirect.github.com/dorny/paths-filter/pull/74">Fix
fetching git history + fallback to unshallow repo</a></li>
</ul>
<h2>v2.9.0</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dorny/paths-filter/commit/fbd0ab8f3e69293af611ebaee6363fc25e6d187d"><code>fbd0ab8</code></a>
feat: add merge_group event support</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/efb1da7ce8d89bbc261191e5a2dc1453c3837339"><code>efb1da7</code></a>
feat: add dist/ freshness check to PR workflow</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/d8f7b061b24c30a325ff314b76c37adb05b041ce"><code>d8f7b06</code></a>
Merge pull request <a
href="https://redirect.github.com/dorny/paths-filter/issues/302">#302</a>
from dorny/issue-299</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/addbc147a95845176e1bc013a012fbf1d366389a"><code>addbc14</code></a>
Update README for v4</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/9d7afb8d214ad99e78fbd4247752c4caed2b6e4c"><code>9d7afb8</code></a>
Update CHANGELOG for v4.0.0</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/782470c5d953cae2693d643172b14e01bacb71f3"><code>782470c</code></a>
Merge branch 'releases/v3'</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/ce10459c8b92cd8901166c0a222fbb033ef39365"><code>ce10459</code></a>
Merge pull request <a
href="https://redirect.github.com/dorny/paths-filter/issues/294">#294</a>
from saschabratton/master</li>
<li><a
href="https://github.com/dorny/paths-filter/commit/5f40380c5482e806c81cec080f5192e7234d8fe9"><code>5f40380</code></a>
feat: update action runtime to node24</li>
<li>See full diff in <a
href="https://github.com/dorny/paths-filter/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 14:54:07 -04:00
dependabot[bot] 76c55a488c Bump node from 156b55f to a0b9bf0 in the docker-base-image-digests group (#1089)
Bumps the docker-base-image-digests group with 1 update: node.

Updates `node` from `156b55f` to `a0b9bf0`


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=node&package-manager=docker&previous-version=24-alpine&new-version=24-alpine)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 14:53:45 -04:00
dependabot[bot] 08d0a04cf2 Bump python from 44dd044 to 63a4c7f (#1090)
Bumps python from `44dd044` to `63a4c7f`.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.14.6-slim&new-version=3.14.6-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-26 14:53:28 -04:00
CaliBrain 36f9a52987 Annotate both the per-platform manifests and the multi-arch image index (#1088)
Fixes #1087
2026-06-24 11:56:57 -04:00
CaliBrain 1536b91a46 Fix e2e scipts (#1086) 2026-06-24 00:09:06 -04:00
CaliBrain fea63269e3 the e2e platform test profiles live in an env/ dir and must be tracked (#1085) 2026-06-23 21:28:25 -04:00
CaliBrain 7886ba7038 fix astral-sh-setup-uv (#1084) 2026-06-23 17:43:59 -04:00
CaliBrain 1c19326bd0 e2e testing 2 (#1083) 2026-06-23 16:58:24 -04:00
CaliBrain 2f70ed36e4 e2e testing (#1082) 2026-06-23 15:38:46 -04:00
dependabot[bot] 8d54cff383 Bump the python-deps group with 3 updates (#1081)
Bumps the python-deps group with 3 updates:
[tqdm](https://github.com/tqdm/tqdm),
[seleniumbase](https://github.com/seleniumbase/SeleniumBase) and
[ruff](https://github.com/astral-sh/ruff).

Updates `tqdm` from 4.68.2 to 4.68.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tqdm/tqdm/releases">tqdm's
releases</a>.</em></p>
<blockquote>
<h2>tqdm v4.68.3 stable</h2>
<ul>
<li><code>utils</code>: delay <code>os.get_terminal_size</code> (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1763">#1763</a> &lt;-
<a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a>)</li>
<li><code>autonotebook</code>: support QtConsole, Spyder, JupyterLite
(<a href="https://redirect.github.com/tqdm/tqdm/issues/1763">#1763</a>,
<a href="https://redirect.github.com/tqdm/tqdm/issues/1628">#1628</a>,
<a href="https://redirect.github.com/tqdm/tqdm/issues/1559">#1559</a>
&lt;- <a
href="https://redirect.github.com/tqdm/tqdm/issues/1283">#1283</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/1098">#1098</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/512">#512</a>)</li>
<li>minor docs updates
<ul>
<li>fix typo (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1762">#1762</a>)</li>
<li>use <code>git-fame</code></li>
</ul>
</li>
<li>misc minor framework updates
<ul>
<li>fix &amp; update CI build</li>
<li>pre-commit: add docs &amp; metadata generation</li>
<li>move <code>tox.ini</code> -&gt; <code>pyproject.toml</code>, move
<code>tox-gh-actions</code> -&gt; <code>tox-gh</code></li>
<li>add Python 3.14, drop 3.7 support</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tqdm/tqdm/commit/9aff6090b6fa98c88a2dbff8bd9e2a68d9a99c1b"><code>9aff609</code></a>
bump version, merge pull request <a
href="https://redirect.github.com/tqdm/tqdm/issues/1763">#1763</a> from
tqdm/jupyterlite</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/9872f80e0d9ceb8377b45c714ec8f6ae66bf9ef9"><code>9872f80</code></a>
drop date from snap version str to fix pydantic</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/b82933405f6dc19dd8f667be57fd2058a00f75c7"><code>b829334</code></a>
support QtConsole, Spyder, JupyterLite</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/6fa4867b27dd4852204aa13f73300db41791cd46"><code>6fa4867</code></a>
delay os.get_terminal_size</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/748e107287c9a66e3a366cd5366bd9a8bcbe33ae"><code>748e107</code></a>
lint</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/e6e29eb7a191d366d21b93817c6de3857b664367"><code>e6e29eb</code></a>
move tox.ini -&gt; pyproject.toml</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/617e4faf67d6cc59d42e3b2665b0c1199a665db4"><code>617e4fa</code></a>
tox-gh-actions -&gt; tox-gh</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/c49c50d83124e514d2b6bb549661ff1e2fa44504"><code>c49c50d</code></a>
add python 3.14, drop python 3.7 support</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/fa2bcdb4ad68d4e95bd49460d8d590451cf478ba"><code>fa2bcdb</code></a>
pre-commit: tqdm.1</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/1ec798811a960294d74d42d35b6614e3273e9fe3"><code>1ec7988</code></a>
auto git-fame</li>
<li>Additional commits viewable in <a
href="https://github.com/tqdm/tqdm/compare/v4.68.2...v4.68.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.49.14 to 4.50.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.50.1 - Fix Layout in Recorder App</h2>
<h2>Fix Layout in Recorder App</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/77cb1e267c04f60c8329ae6a00eb581d003d22fc">Fix
the layout of the SeleniumBase Recorder App</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Fix Layout in Recorder App by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4405">seleniumbase/SeleniumBase#4405</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.50.0...v4.50.1">https://github.com/seleniumbase/SeleniumBase/compare/v4.50.0...v4.50.1</a></p>
<h2>4.50.0 - Improve Recorder and Fix Bugs</h2>
<h2>Improve Recorder and Fix Bugs</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/04acb5e8dc1c3621fe8e36529023a4fae8eebc7f">Improve
the desktop Recorder App and Recorder Mode</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4403">seleniumbase/SeleniumBase#4403</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/8a9a8eb8dbfa6f90166564769fea5244eafaa32f">Fix
sb.solve_captcha() on Windows for Slider CAPTCHAs</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4399">seleniumbase/SeleniumBase#4399</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/8a39a469f0b09b7aff6e7b3e2dc0a7608dbdb027">Prevent
cleanup warnings on Windows</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4400">seleniumbase/SeleniumBase#4400</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d72f80972432117bb23e9a37f2f1e6c8cdbac365">Fix
issue with get_title() failing at random</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4401">seleniumbase/SeleniumBase#4401</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/13796feaaab122cfa8678644d95644d50cd5485f">Update
the docs</a>
-- It's mostly around the updated Recorder</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/221adbf8349cf0632290be5ec8fd1c135c4b9dac">Refresh
Python dependencies</a>
-- <code>selenium</code> and <code>certifi</code></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Improved Recorder App and Bug Fixes by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4404">seleniumbase/SeleniumBase#4404</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.14...v4.50.0">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.14...v4.50.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/93bf553426926a512457dc9e64a5a936e723041a"><code>93bf553</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4405">#4405</a>
from seleniumbase/fix-recorder-app-layout</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/fd8a6965f102f87f548ca2ca07a143ad90e9bd50"><code>fd8a696</code></a>
Version 4.50.1</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/18ee81c21f2a899ca17891c1cee6168ec146a54e"><code>18ee81c</code></a>
Update Recorder App image in a ReadMe</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/77cb1e267c04f60c8329ae6a00eb581d003d22fc"><code>77cb1e2</code></a>
Fix the layout of the SeleniumBase Recorder App</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0c5867d71a4d8b966e61b18b33ac90c9b28ae130"><code>0c5867d</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4404">#4404</a>
from seleniumbase/improved-recorder-app-and-bug-fixes</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a5ac4e8d5b8ae02a591d84c73494e4caaca2c83f"><code>a5ac4e8</code></a>
Version 4.50.0</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/221adbf8349cf0632290be5ec8fd1c135c4b9dac"><code>221adbf</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/27b2fb0a38cdfb5d90aea74235cae8e655c2df1a"><code>27b2fb0</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/13796feaaab122cfa8678644d95644d50cd5485f"><code>13796fe</code></a>
Update the docs</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d72f80972432117bb23e9a37f2f1e6c8cdbac365"><code>d72f809</code></a>
Fix issue with <code>get_title()</code> failing at random</li>
<li>Additional commits viewable in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.14...v4.50.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `ruff` from 0.15.17 to 0.15.18
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.18</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-18.</p>
<h3>Preview features</h3>
<ul>
<li>Handle nested <code>ruff:ignore</code> comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25791">#25791</a>)</li>
<li>Stop displaying severity in output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26050">#26050</a>)</li>
<li>Use human-readable names in CLI output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25937">#25937</a>)</li>
<li>Use human-readable names in LSP and playground diagnostics (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26058">#26058</a>)</li>
<li>[<code>pydocstyle</code>] Prevent property docstrings starting with
verbs (<code>D421</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23775">#23775</a>)</li>
<li>[<code>flake8-pyi</code>] Extend <code>PYI033</code> to Python files
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/26129">#26129</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Detect equivalent numeric mapping keys (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26009">#26009</a>)</li>
<li>Detect mapping keys equivalent to booleans (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25982">#25982</a>)</li>
<li>Detect repeated signed and complex dictionary keys (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26007">#26007</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pyi</code>] Rename <code>PYI033</code> to
<code>legacy-type-comment</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26131">#26131</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Use <code>ThinVec</code> for call keywords (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25999">#25999</a>)</li>
<li>Inline parser recovery context checks (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26038">#26038</a>)</li>
<li>Match parser keywords as bytes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26037">#26037</a>)</li>
<li>Move value parsing out of lexing (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25360">#25360</a>)</li>
</ul>
<h3>Server</h3>
<ul>
<li>Render subdiagnostics and secondary annotations as related
information (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26011">#26011</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Update fix availability for always-fixable rules (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26091">#26091</a>)</li>
<li>[<code>flake8-tidy-imports</code>] Add fix safety section
(<code>TID252</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/17491">#17491</a>)</li>
</ul>
<h3>Parser</h3>
<ul>
<li>Reject <code>__debug__</code> lambda parameters (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26022">#26022</a>)</li>
<li>Reject <code>_</code> as a match-pattern target (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25977">#25977</a>)</li>
<li>Reject multiple starred names in sequence patterns (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25976">#25976</a>)</li>
<li>Reject parenthesized star imports (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26021">#26021</a>)</li>
<li>Reject starred comprehension targets (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26023">#26023</a>)</li>
<li>Reject unparenthesized generator expressions in class bases (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25978">#25978</a>)</li>
<li>Reject <code>yield</code> expressions after commas (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26024">#26024</a>)</li>
<li>Validate function type parameter default order (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25981">#25981</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.18</h2>
<p>Released on 2026-06-18.</p>
<h3>Preview features</h3>
<ul>
<li>Handle nested <code>ruff:ignore</code> comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25791">#25791</a>)</li>
<li>Stop displaying severity in output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26050">#26050</a>)</li>
<li>Use human-readable names in CLI output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25937">#25937</a>)</li>
<li>Use human-readable names in LSP and playground diagnostics (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26058">#26058</a>)</li>
<li>[<code>pydocstyle</code>] Prevent property docstrings starting with
verbs (<code>D421</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23775">#23775</a>)</li>
<li>[<code>flake8-pyi</code>] Extend <code>PYI033</code> to Python files
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/26129">#26129</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Detect equivalent numeric mapping keys (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26009">#26009</a>)</li>
<li>Detect mapping keys equivalent to booleans (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25982">#25982</a>)</li>
<li>Detect repeated signed and complex dictionary keys (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26007">#26007</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pyi</code>] Rename <code>PYI033</code> to
<code>legacy-type-comment</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26131">#26131</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Use <code>ThinVec</code> for call keywords (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25999">#25999</a>)</li>
<li>Inline parser recovery context checks (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26038">#26038</a>)</li>
<li>Match parser keywords as bytes (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26037">#26037</a>)</li>
<li>Move value parsing out of lexing (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25360">#25360</a>)</li>
</ul>
<h3>Server</h3>
<ul>
<li>Render subdiagnostics and secondary annotations as related
information (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26011">#26011</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Update fix availability for always-fixable rules (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26091">#26091</a>)</li>
<li>[<code>flake8-tidy-imports</code>] Add fix safety section
(<code>TID252</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/17491">#17491</a>)</li>
</ul>
<h3>Parser</h3>
<ul>
<li>Reject <code>__debug__</code> lambda parameters (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26022">#26022</a>)</li>
<li>Reject <code>_</code> as a match-pattern target (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25977">#25977</a>)</li>
<li>Reject multiple starred names in sequence patterns (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25976">#25976</a>)</li>
<li>Reject parenthesized star imports (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26021">#26021</a>)</li>
<li>Reject starred comprehension targets (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26023">#26023</a>)</li>
<li>Reject unparenthesized generator expressions in class bases (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25978">#25978</a>)</li>
<li>Reject <code>yield</code> expressions after commas (<a
href="https://redirect.github.com/astral-sh/ruff/pull/26024">#26024</a>)</li>
<li>Validate function type parameter default order (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25981">#25981</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/ruff/commit/6686f63404207bfdffe8ab0acb25da72c3432190"><code>6686f63</code></a>
Bump 0.15.18 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26135">#26135</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/efbb7325ff5bb92b0a0c0a0efa0ac94e439ee367"><code>efbb732</code></a>
[ty] Suggest keyword-only arguments between variadic parameters (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26134">#26134</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/c256d5f573e66612556061bfd0af527136a23c30"><code>c256d5f</code></a>
[ty] Support <code>Annotated[Any, ...]</code> as a class base (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26133">#26133</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/19a4bea1af5b252798d85696f2f397dae91d303d"><code>19a4bea</code></a>
[flake8-pyi] Rename PYI033 to legacy-type-comment (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26131">#26131</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/1d9866cbd673dc68153ad162465e979c47e62a96"><code>1d9866c</code></a>
Bump ecosystem-analyzer commit (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26130">#26130</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/8656c731dded1e91c0e2713405e43bb2c4eb53bf"><code>8656c73</code></a>
[ty] Compact indexed AST node storage (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25998">#25998</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/c17c8d9a060f839c0f9b69c69b85d3802ec5dfdf"><code>c17c8d9</code></a>
[ty] Garbage-collect cached constraint sets (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26116">#26116</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/ef0fb8fa264035974e57fda59e2baf196ec1fb9e"><code>ef0fb8f</code></a>
[ty] Fix bound TypeVar default cycle recovery (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26124">#26124</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/b83c02489df8bccda7313a2cdd8369c9b5d1b002"><code>b83c024</code></a>
[flake8-pyi] Extend PYI033 to Python files in preview (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26129">#26129</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/e8a5e38858558a68e94397152fd735cacb6ea3b4"><code>e8a5e38</code></a>
Update Rust crate zip to v8 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/26078">#26078</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.15.17...0.15.18">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-22 13:36:49 -04:00
dependabot[bot]andCaliBrain 63fa6213da Bump the npm-deps group in /src/frontend with 6 updates (#1077)
Bumps the npm-deps group in /src/frontend with 6 updates:

| Package | From | To |
| --- | --- | --- |
|
[@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)
| `4.3.0` | `4.3.1` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) |
`6.16.1` | `6.17.0` |
| [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) |
`0.54.0` | `0.55.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) |
`1.69.0` | `1.70.0` |
|
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)
| `4.3.0` | `4.3.1` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.8` | `4.1.9` |

Updates `@tailwindcss/vite` from 4.3.0 to 4.3.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">@​tailwindcss/vite's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.1</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
<li>Generate <code>var(--spacing)</code> instead of
<code>calc(var(--spacing) * 1)</code> for spacing utilities like
<code>m-1</code> and <code>left-1</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@​tailwindcss/vite's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.1] - 2026-06-12</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
<li>Generate <code>var(--spacing)</code> instead of
<code>calc(var(--spacing) * 1)</code> for spacing utilities like
<code>m-1</code> and <code>left-1</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8a14a710102cae195f6811e8578bef9477bc6be9"><code>8a14a71</code></a>
4.3.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20226">#20226</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/73983e1cf5bc0ae721f4568cc24a5b5067b6b90b"><code>73983e1</code></a>
Fix 'Sourcemap is likely to be incorrect' warnings when using
`@tailwindcss/v...</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/@tailwindcss-vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.16.1 to 6.17.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.17.0</h2>
<ul>
<li>chore(mcp): add package metadata links (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1783">#1783</a>)
(e3d93b930) - thanks <a
href="https://github.com/sh962214-hub"><code>@​sh962214-hub</code></a>!</li>
<li>fix(capacitor): detect iOS platform with Swift Package Manager (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1787">#1787</a>)
(e6cc533a8) - thanks <a
href="https://github.com/jthrilly"><code>@​jthrilly</code></a>!</li>
<li>Support ignoreIssues per workspace (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1782">#1782</a>)
(15a329a05)</li>
<li>Add commitlint.config.mts (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1784">#1784</a>)
(fa8eb6da8)</li>
<li>Treat scoped and tilde SCSS imports as packages (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1786">#1786</a>)
(98aa9623e)</li>
<li>Add followCursor setting for Imports/Exports views (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1788">#1788</a>)
(67a0be89f)</li>
<li>Flag undeclared sibling imports in published workspaces (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1792">#1792</a>)
(aeabff789)</li>
<li>Fix type-check errors in vscode-knip (12f266e94)</li>
<li>Note Markdown formatting with pnpm remark (bdffeec0d)</li>
<li>Bump some doc-related dependencies (333419303)</li>
<li>Update vscode-knip tool descriptions (be341788c)</li>
<li>Overhaul docs (55e3f3bda)</li>
<li>Improve mcp guidance (67483f0ac)</li>
<li>Fix repeated --fix-type arg (9bb0512ca)</li>
<li>Resolve module paths from selected tsconfig (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1794">#1794</a>)
(1c2f39833)</li>
<li>Update sanity snapshot (4ebce9c50)</li>
<li>Add tar to globally ignored binaries (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1796">#1796</a>)
(8c028e5fb)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/dd0c682f9c41cfcd428458ece2cd32553824a550"><code>dd0c682</code></a>
Release knip@6.17.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/8c028e5fb25e989591689805c335ffd80a651bfd"><code>8c028e5</code></a>
Add tar to globally ignored binaries (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1796">#1796</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/1c2f398331fddc9beddfc438ac5ce529ec9e070c"><code>1c2f398</code></a>
Resolve module paths from selected tsconfig (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1794">#1794</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/9bb0512ca0e06f61117076fb8bfa806dfe3f7fb1"><code>9bb0512</code></a>
Fix repeated --fix-type arg</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/67483f0ac6ea6845631ffdef0425de6b41092e26"><code>67483f0</code></a>
Improve mcp guidance</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/aeabff789071e7451ed88744ac70621d6d29249f"><code>aeabff7</code></a>
Flag undeclared sibling imports in published workspaces (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1792">#1792</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/98aa9623e3794b6fe783e0ce2c11a0e4acf2b8c2"><code>98aa962</code></a>
Treat scoped and tilde SCSS imports as packages (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1786">#1786</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/fa8eb6da81066f835fbca05d640348bd9b2b8eda"><code>fa8eb6d</code></a>
Add commitlint.config.mts (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1784">#1784</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/15a329a0555b3496fe4018a39cb5cb734fbb9eba"><code>15a329a</code></a>
Support ignoreIssues per workspace (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1782">#1782</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/e6cc533a8772cdc4aba93cac376d214fb2fb5a58"><code>e6cc533</code></a>
fix(capacitor): detect iOS platform with Swift Package Manager (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1787">#1787</a>)</li>
<li>See full diff in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.17.0/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.54.0 to 0.55.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxfmt/CHANGELOG.md">oxfmt's
changelog</a>.</em></p>
<blockquote>
<h2>[0.55.0] - 2026-06-15</h2>
<h3>🚀 Features</h3>
<ul>
<li>9a2788b linter/unicorn: Implement <code>prefer-export-from</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22935">#22935</a>)
(AliceLanniste)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/aa79b5be9915068f60bc361febf2e7496b92fc24"><code>aa79b5b</code></a>
release(apps): oxlint v1.70.0 &amp;&amp; oxfmt v0.55.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/23442">#23442</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/9a2788b3ae60c033a969fbba63733748f8c6130a"><code>9a2788b</code></a>
feat(linter/unicorn): implement <code>prefer-export-from</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22935">#22935</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.55.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.69.0 to 1.70.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.70.0] - 2026-06-15</h2>
<h3>🚀 Features</h3>
<ul>
<li>2e8bda4 linter/vue: Implement no-dupe-keys rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23350">#23350</a>)
(bab)</li>
<li>1490a0a linter/react: Implement react-compiler rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23202">#23202</a>)
(Boshen)</li>
<li>dd560ae linter/unicorn: Implement
<code>no-array-fill-with-reference-type</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23397">#23397</a>)
(Mikhail Baev)</li>
<li>af36c2f linter: Add schema for
<code>react/jsx-curly-brace-presence</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23400">#23400</a>)
(WaterWhisperer)</li>
<li>47d34a3 linter: Add schema for <code>react/jsx-handler-names</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23393">#23393</a>)
(WaterWhisperer)</li>
<li>f4250d0 linter: Add schema for <code>unicorn/import-style</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23386">#23386</a>)
(WaterWhisperer)</li>
<li>30c74ce linter: Add schema for
<code>jsx_a11y/no-noninteractive-element-to-interactive-role</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23384">#23384</a>)
(Sysix)</li>
<li>cfbe8dc linter: Add schema for
<code>jsx_a11y/no-interactive-element-to-noninteractive-role</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23382">#23382</a>)
(WaterWhisperer)</li>
<li>d15b7ff linter: Add schema for
<code>typescript/no-restricted-types</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23381">#23381</a>)
(WaterWhisperer)</li>
<li>028a811 linter: Add schema for
<code>jsx-a11y/media-has-caption</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23377">#23377</a>)
(Sysix)</li>
<li>b3b1038 linter: Add schema for
<code>jsx-a11y/label-has-associated-control</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23376">#23376</a>)
(Sysix)</li>
<li>7ada6b2 linter: Add schema for
<code>jsx_a11y/no-distracting-elements</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23379">#23379</a>)
(WaterWhisperer)</li>
<li>ee3dd49 linter: Add schema for
<code>jsx-a11y/img-redundant-alt</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23374">#23374</a>)
(Sysix)</li>
<li>df5f8dd linter: Add short descriptions to most lint rules. (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23365">#23365</a>)
(Connor Shea)</li>
<li>e3fd735 linter: Add schema for <code>jsx_a11y/alt-text</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23369">#23369</a>)
(Sysix)</li>
<li>0f2fff4 linter: Add schema for <code>react/exhaustive-deps</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23372">#23372</a>)
(Mikhail Baev)</li>
<li>e3e4e10 linter: Add schema for
<code>react_perf/jsx-no-new-object-as-prop</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23368">#23368</a>)
(Mikhail Baev)</li>
<li>9366d44 linter: Add schema for <code>unicorn/prefer-at</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23366">#23366</a>)
(WaterWhisperer)</li>
<li>f57b55d linter: Add schema for <code>typescript/array-type</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23355">#23355</a>)
(Sysix)</li>
<li>0dcf912 linter: Add schema for
<code>typescript/ban-ts-comment</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23354">#23354</a>)
(Sysix)</li>
<li>51fa83e linter: Add schema for
<code>react/no-did-update-set-state</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23357">#23357</a>)
(Mikhail Baev)</li>
<li>59db0bd linter: Add schema for
<code>consistent-generic-constructors</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23353">#23353</a>)
(Sysix)</li>
<li>c4775c0 linter: Add schema for
<code>typescript/consistent-type-assertions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23349">#23349</a>)
(Sysix)</li>
<li>6e516f7 linter: Add schema for
<code>typescript/consistent-type-imports</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23348">#23348</a>)
(Sysix)</li>
<li>012134d linter: Add schema for
<code>react/jsx-no-target-blank</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23345">#23345</a>)
(WaterWhisperer)</li>
<li>0806aae linter: Add schema for
<code>jsx_a11y/no-noninteractive-tabindex</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23337">#23337</a>)
(Mikhail Baev)</li>
<li>0708b5a linter: Add schema for
<code>react/jsx-filename-extension</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23315">#23315</a>)
(Mikhail Baev)</li>
<li>150bce1 linter: Add schema for
<code>typescript/no-empty-object-type</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23309">#23309</a>)
(Sysix)</li>
<li>f9e36f1 linter: Add schema for
<code>typescript/no-duplicate-type-constituents</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23308">#23308</a>)
(Sysix)</li>
<li>937accf linter: Add schema for
<code>typescript/no-invalid-void-type</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23307">#23307</a>)
(Sysix)</li>
<li>3e042b9 linter: Add schema for
<code>typescript/no-misused-promises</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23306">#23306</a>)
(Sysix)</li>
<li>da212d1 linter: Add schema for
<code>typescript/no-unnecessary-condition</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23305">#23305</a>)
(Sysix)</li>
<li>f8f0d38 linter: Add schema for
<code>typescript/parameter-properties</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23304">#23304</a>)
(Sysix)</li>
<li>2275fc7 linter: Add schema for
<code>typescript/prefer-nullish-coalescing</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23302">#23302</a>)
(Sysix)</li>
<li>d353858 linter: Add schema for
<code>typescript/prefer-string-starts-ends-with</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23301">#23301</a>)
(Sysix)</li>
<li>03060f5 linter: Add schema for
<code>typescript/triple-slash-reference</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23300">#23300</a>)
(Sysix)</li>
<li>6619cee linter: Add schema for <code>promise/param-names</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23298">#23298</a>)
(Sysix)</li>
<li>8bf108e linter: Add schema for <code>promise/catch-or-return</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23297">#23297</a>)
(Sysix)</li>
<li>48158d0 linter: Add schema for
<code>vitest/consistent-each-for</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23294">#23294</a>)
(Sysix)</li>
<li>7e74c98 linter: Add schema for
<code>vitest/consistent-test-filename</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23293">#23293</a>)
(Sysix)</li>
<li>ff94d4a linter: Add schema for
<code>vitest/consistent-vitest-vi</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23292">#23292</a>)
(Sysix)</li>
<li>2409a10 linter: Add schema for
<code>vitest/prefer-import-in-mock</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23291">#23291</a>)
(Sysix)</li>
<li>3d782b7 linter: Add schema for
<code>react/no-unstable-nested-components</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23287">#23287</a>)
(Mikhail Baev)</li>
<li>0a0bc2f linter/jsx-a11y: Add <code>allowedRedundantRoles</code>
option to <code>no-redundant-roles</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22820">#22820</a>)
(bab)</li>
<li>80758a5 linter/vue: Implement no-side-effects-in-computed-properties
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23282">#23282</a>)
(bab)</li>
<li>e3869ac linter: Add schema for
<code>react/no-object-type-as-default-prop</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23279">#23279</a>)
(Mikhail Baev)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/aa79b5be9915068f60bc361febf2e7496b92fc24"><code>aa79b5b</code></a>
release(apps): oxlint v1.70.0 &amp;&amp; oxfmt v0.55.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23442">#23442</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/5cb8d1bcf0c63b34ba91e9f9c36e7a84c76cb496"><code>5cb8d1b</code></a>
fix(linter/jsx-a11y/control-has-associated-label): reject excessive
label dep...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/f682e253892e8e77d7700d1053234e7a53c0dbca"><code>f682e25</code></a>
docs(linter): remove manually written options doc for
`eslint/prefer-arrow-ca...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/2e8bda49991cfef9cb9182d37e9f304372f53839"><code>2e8bda4</code></a>
feat(linter/vue): implement no-dupe-keys rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23350">#23350</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/64c942cffe0e8829293d1d9f2f046b496759609a"><code>64c942c</code></a>
docs(linter): remove manually written options doc for
<code>eslint/no-sequences</code> (...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/1490a0a0691908df0ff6659750ca2f3a29396c1a"><code>1490a0a</code></a>
feat(linter/react): implement react-compiler rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23202">#23202</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/965358e6132e84b1828b82e0e8b17f8ac2dec54b"><code>965358e</code></a>
refactor(linter): reuse <code>RuleNoConfig</code> reference for rule
schema (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23390">#23390</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/dd560ae213490fb208fdaa278562cf9169777f86"><code>dd560ae</code></a>
feat(linter/unicorn): implement
<code>no-array-fill-with-reference-type</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23">#23</a>...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/af36c2f9cd497c2f233de1902fc96b88804a2d3c"><code>af36c2f</code></a>
feat(linter): add schema for <code>react/jsx-curly-brace-presence</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23400">#23400</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/47d34a304c83f9a34d78d2895c3616206f5888a1"><code>47d34a3</code></a>
feat(linter): add schema for <code>react/jsx-handler-names</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23393">#23393</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.70.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />

Updates `tailwindcss` from 4.3.0 to 4.3.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.1</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
<li>Generate <code>var(--spacing)</code> instead of
<code>calc(var(--spacing) * 1)</code> for spacing utilities like
<code>m-1</code> and <code>left-1</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">tailwindcss's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.1] - 2026-06-12</h2>
<h3>Added</h3>
<ul>
<li>Add <code>--silent</code> option to suppress output in
<code>@tailwindcss/cli</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20100">#20100</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Remove deprecation warnings by using
<code>Module#registerHooks</code> instead of
<code>Module#register</code> on Node 26+ (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20028">#20028</a>)</li>
<li>Canonicalization: don't crash when plugin utilities throw for
unsupported values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20052">#20052</a>)</li>
<li>Allow <code>@apply</code> to be used with CSS mixins (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19427">#19427</a>)</li>
<li>Ensure <code>not-*</code> correctly negates <code>@container</code>
queries, including <code>style(…)</code> queries (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20059">#20059</a>)</li>
<li>Ensure <code>drop-shadow-*</code> color utilities work with custom
shadow values containing <code>calc(…)</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20080">#20080</a>)</li>
<li>Fix 'Sourcemap is likely to be incorrect' warnings when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20103">#20103</a>)</li>
<li>Ensure <code>@tailwindcss/webpack</code> can be installed in Rspack
projects without requiring <code>webpack</code> as a peer dependency (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20027">#20027</a>)</li>
<li>Canonicalization: don't suggest invalid <code>calc(…)</code>
expressions (e.g. <code>px-[calc(1rem+0px)]</code> →
<code>px-[calc(1rem+0)]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20127">#20127</a>)</li>
<li>Canonicalization: avoid suggesting large spacing-scale values for
arbitrary lengths (e.g. <code>left-[99999px]</code> →
<code>left-[99999px]</code>, not <code>left-24999.75</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20130">#20130</a>)</li>
<li>Ensure <code>@tailwindcss/cli</code> in <code>--watch</code> mode
recovers when a tracked dependency is deleted and restored (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20137">#20137</a>)</li>
<li>Ensure standalone <code>@tailwindcss/cli</code> binaries are ignored
when scanning for class candidates (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20139">#20139</a>)</li>
<li>Ensure class candidates are extracted from Twig
<code>addClass(…)</code> and <code>removeClass(…)</code> calls (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20198">#20198</a>)</li>
<li>Don't crash in the Ruby or Vue preprocessors when scanning files
containing invalid UTF-8 bytes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19588">#19588</a>)</li>
<li>Allow <code>@variant</code> to be used inside <code>addBase</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19480">#19480</a>)</li>
<li>Ensure <code>@source</code> globs with symlinks are preserved (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Ensure later <code>@source</code> rules can re-include files
excluded by earlier <code>@source not</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20203">#20203</a>)</li>
<li>Upgrade: don't migrate empty class rules to invalid
<code>@utility</code> rules (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20205">#20205</a>)</li>
<li>Ensure transitions between <code>inset-shadow-none</code> and other
inset shadows work correctly (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20208">#20208</a>)</li>
<li>Ensure explicitly referenced <code>@source</code> directories are
scanned even when ignored by git (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20214">#20214</a>)</li>
<li>Ensure <code>@source</code> globs ending in <code>**/*</code>
preserve dynamic path segments to avoid scanning too many files (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20217">#20217</a>)</li>
<li>Canonicalization: don't fold <code>calc(…)</code> divisions when the
result would require high precision (e.g.
<code>w-[calc(100%/3.5)]</code> → <code>w-[calc(100%/3.5)]</code>, not
<code>w-[28.571428571428573%]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20221">#20221</a>)</li>
<li>Serve ESM type declarations to ESM importers of
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20228">#20228</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Generate <code>0</code> instead of <code>calc(var(--spacing) *
0)</code> for spacing utilities like <code>m-0</code> and
<code>left-0</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
<li>Generate <code>var(--spacing)</code> instead of
<code>calc(var(--spacing) * 1)</code> for spacing utilities like
<code>m-1</code> and <code>left-1</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20196">#20196</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8a14a710102cae195f6811e8578bef9477bc6be9"><code>8a14a71</code></a>
4.3.1 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20226">#20226</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/12833aa4b3a8813fd32da74be7a2fd75aa706ab7"><code>12833aa</code></a>
Fix canonicalization bug where we end up with a high precision number
(<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20221">#20221</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/97a5b3abfb75ce9722266cd323a24eee057634fc"><code>97a5b3a</code></a>
docs: fix double word 'to to' in test comment (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20216">#20216</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/d01e103cc4741c29764afaa287d2fb21356f7eea"><code>d01e103</code></a>
Add missing <code>inset</code> keyword for
<code>inset-shadow-none</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20208">#20208</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/ad6693906a321912c90fd13c4a92e2cb26660985"><code>ad66939</code></a>
Allow <code>@variant</code> to be used inside <code>addBase</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19480">#19480</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/efae52c3af50300d5066596a6acbaf87e68ef9e4"><code>efae52c</code></a>
Simplify CSS when using utilities that use a <code>*-0</code> or
<code>*-1</code> value (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20196">#20196</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/6b43b6400a743a508afd712b50a73b2d3feb6444"><code>6b43b64</code></a>
Canonicalization: limit arbitrary to bare values conversion (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20130">#20130</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/d4f24c5f161b553dd99aef294ef6635093d1c440"><code>d4f24c5</code></a>
Fix invalid canonicalization where <code>0\&lt;unit&gt;</code> was
migrated to <code>0</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20127">#20127</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/749c45ef26735c59a446fc5e13e96359b68b9082"><code>749c45e</code></a>
Expose <code>index</code> and <code>siblings</code> on walk context (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20109">#20109</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/8dcdb66e8a58b9df621ed1a9cb59396e0ddb6dd7"><code>8dcdb66</code></a>
Bump dependencies (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/20095">#20095</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/tailwindcss">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 4.1.8 to 4.1.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.9</h2>
<h3>🐞 Bug Fixes</h3>
<ul>
<li>Fix <code>importOriginal</code> with optimizer and query import
[backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>David
Harris</strong>, <strong>Codex</strong>and <strong>Vladimir</strong> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10546">vitest-dev/vitest#10546</a>
<a href="https://github.com/vitest-dev/vitest/commit/a5180190c"><!-- raw
HTML omitted -->(a5180)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>:
<ul>
<li>Wait for orchestrator readiness before resolving browser sessions
[backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus
O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10555">vitest-dev/vitest#10555</a>
<a href="https://github.com/vitest-dev/vitest/commit/7fb29651a"><!-- raw
HTML omitted -->(7fb29)<!-- raw HTML omitted --></a></li>
<li>Wait for iframe tester readiness before preparing [backport to v4] -
by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10497">vitest-dev/vitest#10497</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10556">vitest-dev/vitest#10556</a>
<a href="https://github.com/vitest-dev/vitest/commit/fbc626c40"><!-- raw
HTML omitted -->(fbc62)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>mocker</strong>:
<ul>
<li>Hoist vi.mock() for vite-plus/test imports [backport to v4] - by
<strong>Hiroshi Ogawa</strong>, <strong>LongYinan</strong>,
<strong>Claude Opus 4.8</strong> and <strong>Vladimir</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10548">vitest-dev/vitest#10548</a>
<a href="https://github.com/vitest-dev/vitest/commit/2c9559c02"><!-- raw
HTML omitted -->(2c955)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>pool</strong>:
<ul>
<li>Prevent test run hang on worker crash [backport to v4] - by
<strong>Ari Perkkiö</strong> and <strong>Jattioui Ismail</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10543">vitest-dev/vitest#10543</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10564">vitest-dev/vitest#10564</a>
<a href="https://github.com/vitest-dev/vitest/commit/934b0f587"><!-- raw
HTML omitted -->(934b0)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5><a
href="https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4"><code>a7a61e7</code></a>
chore: release v4.1.9 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10598">#10598</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/934b0f587cb61d8338d83f525295322692a2db40"><code>934b0f5</code></a>
fix(pool): prevent test run hang on worker crash (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10543">#10543</a>)
[backport to v4] (#...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/7fb29651afbae2a9b0cefe6c031a9308f168ac60"><code>7fb2965</code></a>
fix(browser): wait for orchestrator readiness before resolving browser
sessio...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a5180190c1be7089e3705e3dd9e84fea118d09d3"><code>a518019</code></a>
fix: fix <code>importOriginal</code> with optimizer and query import
[backport to v4] (#...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-21 00:58:18 -04:00
CaliBrain 61b3eaf351 Fix internal bypasser using system DNS in subprocess, breaking downloads behind ISP DNS blocks (#1028) (#1080) 2026-06-21 00:42:03 -04:00
dependabot[bot] 7158b79146 Bump the python-deps group with 3 updates (#1074)
Bumps the python-deps group with 3 updates:
[python-socketio](https://github.com/miguelgrinberg/python-socketio),
[seleniumbase](https://github.com/seleniumbase/SeleniumBase) and
[prek](https://github.com/j178/prek).

Updates `python-socketio` from 5.16.2 to 5.16.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/miguelgrinberg/python-socketio/releases">python-socketio's
releases</a>.</em></p>
<blockquote>
<h2>Release 5.16.3</h2>
<p>See <a
href="https://github.com/miguelgrinberg/python-socketio/blob/main/CHANGES.md">CHANGES.md</a>
for release notes.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/miguelgrinberg/python-socketio/blob/main/CHANGES.md">python-socketio's
changelog</a>.</em></p>
<blockquote>
<h1>python-socketio change log</h1>
<p><strong>Release 5.16.3</strong> - 2026-06-15</p>
<ul>
<li>Catch all exceptions in redis and rabbitmq client managers <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1581">#1581</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/80bb5c9b07e6b53e45f610ec29a24124c539d41b">commit</a>)</li>
</ul>
<p><strong>Release 5.16.2</strong> - 2026-05-21</p>
<ul>
<li>Prevent unnecessary resource allocations <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1574">#1574</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/ca140fe44d0ceb3004073645222abec182d8784b">commit</a>)</li>
<li>Add zizmor to CI builds <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1570">#1570</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/664dc27ec6f34179ed1724430eda3520627fc642">commit</a>)</li>
</ul>
<p><strong>Release 5.16.1</strong> - 2026-02-06</p>
<ul>
<li>Use configured JSON module in managers <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1549">#1549</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/6229261ae6e8c01e675097242e333ee84587a544">commit</a>)</li>
<li>Admin UI fixes: remove duplicate tasks, report transport upgrades
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1c2eab13a92fac9e43663eb0b5f099eb1c40ea5b">commit</a>)</li>
<li>Switch to Furo documentation template (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/add47d8c7abca697a2804141bbf29bfb095f7d5e">commit</a>)</li>
<li>Add Python free-threading to CI <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1554">#1554</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/ccdd2004a038ae4b8171a05120c5d0787332f7ee">commit</a>)</li>
</ul>
<p><strong>Release 5.16.0</strong> - 2025-12-24</p>
<ul>
<li>Address deprecation warnings (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/b235699d9b06564753c570b76055997e9d62a938">commit</a>)</li>
<li>Drop Python 3.8 and 3.9 from CI builds (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/d0728d2f74538762dd551fa9cd0cd1fd5aedfa37">commit</a>)</li>
</ul>
<p><strong>Release 5.15.1</strong> - 2025-12-16</p>
<ul>
<li>Restore support multiple arguments via pubsub emits <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1540">#1540</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/c279f26bb8c9887c4ca99d4d81ad331c4844438c">commit</a>)</li>
</ul>
<p><strong>Release 5.15.0</strong> - 2025-11-22</p>
<ul>
<li>Retry initial Redis connection <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1536">#1534</a>
([commit <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1">#1</a>](<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1e903e173a2d7b04599c4f7f9630c1abbb531fad">https://github.com/miguelgrinberg/python-socketio/commit/1e903e173a2d7b04599c4f7f9630c1abbb531fad</a>)
[commit <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/2">#2</a>](<a
href="https://github.com/miguelgrinberg/python-socketio/commit/5e898a9b93526e6e667767e54c60f4c84589989d">https://github.com/miguelgrinberg/python-socketio/commit/5e898a9b93526e6e667767e54c60f4c84589989d</a>))</li>
<li>Correctly regenerate RabbitMQ binding after a connection failure <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1516">#1516</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/c52e93b4a328d98a968bfbdec0cfd598b73ee913">commit</a>)
(thanks <strong>Gritty_dev</strong>!)</li>
<li>Support <code>ext_type</code> in the <code>MsgPackPacket</code>
class <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1521">#1521</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/208925344a48485d2cd56e40eb74266c3bcb5311">commit</a>)</li>
<li>Support sending <code>bytesarray</code>s when using pub/sub managers
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/6c9b9974f72e2efdf62407ecab24ee6995448098">commit</a>)</li>
<li>Fix typos in documentation <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1520">#1520</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/db3f1c2a0105c30cb833ddfca8f05fe4320468fd">commit</a>)
(thanks <strong>Lê Nam Khánh</strong>!)</li>
<li>Improvements to the logging documentation (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/b423d0e38eef559b7e81acb7e32059de305f982c">commit</a>)</li>
</ul>
<p><strong>Release 5.14.3</strong> - 2025-10-29</p>
<ul>
<li>Support Python's native <code>ConnectionRefusedError</code>
exception to reject a connection <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1515">#1515</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/f3b18bde3f16437b223491d4c3e440ea37105fe3">commit</a>)</li>
<li>Push binary data to the aiopika client manager <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1514">#1514</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/194e1b7f277b5f72e1de78d3f614e7b8b6c788ac">commit</a>)</li>
</ul>
<p><strong>Release 5.14.2</strong> - 2025-10-15</p>
<ul>
<li>Restore binary message support in message queue setups <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1509">#1509</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/bab4a10f48aaae11d7f832ebe5c30ad3f85d31b3">commit</a>)</li>
<li>Fix formatting of client connection error <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1507">#1507</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/f298c9b54d76ab09ff72935937e1b9575bc45ffd">commit</a>)</li>
<li>Add 3.14 and pypy-3.11 CI tasks (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1f4cd3b025c294f25208ec3c05b5f8df6209e403">commit</a>)</li>
<li>Improve documentation of the
<code>BaseManager.get_participants()</code> method (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/33722a0d96036f005188b07b8b46a5ef091fe65f">commit</a>)</li>
</ul>
<p><strong>Release 5.14.1</strong> - 2025-10-02</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/36c550f62415dc9c9c8dd39203b3c59ec7bdcdea"><code>36c550f</code></a>
Release 5.16.3</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/80bb5c9b07e6b53e45f610ec29a24124c539d41b"><code>80bb5c9</code></a>
Catch all exceptionsin redis and rabbitmq managers (Fixes <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1581">#1581</a>)</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/3f1d50903d1034fd9ffeb2110465ee0c1f90ea4c"><code>3f1d509</code></a>
Bump aiohttp from 3.13.4 to 3.14.0 in /examples/server/aiohttp (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1580">#1580</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/c2918c1b43489bde34d9198352bc1a4667021fc0"><code>c2918c1</code></a>
Bump qs and express in /examples/server/javascript (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1579">#1579</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/e19cb7df63e132da3a9b599e5bf948199c6a524f"><code>e19cb7d</code></a>
Bump qs and express in /examples/client/javascript (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1578">#1578</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/f616fb1cb4ba766bac99b05553672e8d3de90b48"><code>f616fb1</code></a>
Bump ws, engine.io, socket.io-adapter and socket.io-client (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1575">#1575</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/5f35b0bf5bb959b0a0b0d5006040a53112b50633"><code>5f35b0b</code></a>
Bump ws, engine.io, socket.io-adapter and socket.io-client (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1576">#1576</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/995f0807e78207ec88872764f7533a115fb9c6ba"><code>995f080</code></a>
Version 5.16.3.dev0</li>
<li>See full diff in <a
href="https://github.com/miguelgrinberg/python-socketio/compare/v5.16.2...v5.16.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.49.13 to 4.49.14
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.14 - Chromium overhaul with CDP Mode updates</h2>
<h2>Chromium overhaul with CDP Mode updates</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cb03afab9f8aeb67273348a8f5641faaf8ed90e7">Fix
issue that caused Chromium 151 to crash at startup</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4393">seleniumbase/SeleniumBase#4393</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/14d688b69f065f51d5b7b5d87059a591ad0a59d2">Add
option for setting the exact Chromium revision to download</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4394">seleniumbase/SeleniumBase#4394</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3c729af379fffaf2365782ea400d57d8f01e75a1">Update
Chromium options</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4395">seleniumbase/SeleniumBase#4395</a>
-- this resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4396">seleniumbase/SeleniumBase#4396</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f01f59153b338246ec6e78e589b00463107542ad">Update
CDP Mode</a></li>
</ul>
<h3>Here's an example of downloading a custom Chromium revision:</h3>
<pre lang="zsh"><code>sbase get chromium --revision=1639046
<p>*** Chromium revision to download = 1639046</p>
<p>Downloading chrome-mac.zip from:
<a
href="https://storage.googleapis.com/chromium-browser-snapshots/Mac_Arm/1639046/chrome-mac.zip">https://storage.googleapis.com/chromium-browser-snapshots/Mac_Arm/1639046/chrome-mac.zip</a>
...
Download Complete!</p>
<p>... [UNZIPPING] ...</p>
<p>Unzip Complete!</p>
<p>Chromium was saved inside:
..../seleniumbase/drivers/chromium_drivers/
chrome-mac
</code></pre></p>
<h2>What's Changed</h2>
<ul>
<li>Chromium overhaul with CDP Mode updates by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4397">seleniumbase/SeleniumBase#4397</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.13...v4.49.14">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.13...v4.49.14</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/dd5454faf2ba9950da5390d4dd121d17bb3b7f2c"><code>dd5454f</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4397">#4397</a>
from seleniumbase/chromium-overhaul-with-cdp-updates</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/520c0b406a784c48be94ed6dbdcc85dbd469c6dd"><code>520c0b4</code></a>
Version 4.49.14</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0e11a764a656f1bfc65998dafa3f7a4eed96104b"><code>0e11a76</code></a>
Update the docs</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/b1901439ba8eb54dadc1a87816216bddf24b9e0e"><code>b190143</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f01f59153b338246ec6e78e589b00463107542ad"><code>f01f591</code></a>
Update CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3c729af379fffaf2365782ea400d57d8f01e75a1"><code>3c729af</code></a>
Update Chromium options</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/14d688b69f065f51d5b7b5d87059a591ad0a59d2"><code>14d688b</code></a>
Add option for setting the exact Chromium revision to download</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cb03afab9f8aeb67273348a8f5641faaf8ed90e7"><code>cb03afa</code></a>
Fix issue that caused Chromium 151 to crash at startup</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d76b2fd98f4c71a930b8b0536235cd9e7118d9f4"><code>d76b2fd</code></a>
Update CDP Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/09fd1f35d284965ddf8a4b245710d9acee6a6e3e"><code>09fd1f3</code></a>
Add/update examples of DataDome Slider CAPTCHA-bypass</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.13...v4.49.14">compare
view</a></li>
</ul>
</details>
<br />

Updates `prek` from 0.4.4 to 0.4.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.5</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-15.</p>
<h3>✨Highlights</h3>
<p>0.4.5 completes <code>prek</code>'s pre-commit language coverage.
With R, Conda, Perl,
and coursier now supported, <code>prek</code> supports every language
available in
pre-commit, plus <code>prek</code>-only modern languages such as Bun and
Deno.</p>
<p>This is full feature parity with pre-commit. The last major
compatibility gap
is closed, and <code>prek</code> is now on the path to 1.0.</p>
<h3>💚 Sponsorship</h3>
<p>If <code>prek</code> saves time for you or your team, please consider
sponsoring the
project on <a href="https://github.com/sponsors/j178">GitHub
Sponsors</a>. It helps keep
new features, performance work, and maintenance moving.</p>
<h3>Enhancements</h3>
<ul>
<li>Add <code>Perl</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2201">#2201</a>)</li>
<li>Add <code>R</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2206">#2206</a>)</li>
<li>Add <code>Conda</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2203">#2203</a>)</li>
<li>Add <code>coursier</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2194">#2194</a>)</li>
<li>Add group filters to list (<a
href="https://redirect.github.com/j178/prek/pull/2152">#2152</a>)</li>
<li>Remove legacy repo path support (<a
href="https://redirect.github.com/j178/prek/pull/2150">#2150</a>)</li>
<li>Skip cloning fully filtered remote repos (<a
href="https://redirect.github.com/j178/prek/pull/2151">#2151</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid building JSON trees in syntax hooks (<a
href="https://redirect.github.com/j178/prek/pull/2156">#2156</a>)</li>
<li>Scan mixed line endings without line vector (<a
href="https://redirect.github.com/j178/prek/pull/2160">#2160</a>)</li>
<li>Skip file scan for always-run no-filename hooks (<a
href="https://redirect.github.com/j178/prek/pull/2155">#2155</a>)</li>
<li>Use fixed buffer for EOF scan (<a
href="https://redirect.github.com/j178/prek/pull/2163">#2163</a>)</li>
<li>Use fixed buffer for private key scan (<a
href="https://redirect.github.com/j178/prek/pull/2164">#2164</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix pretty-format-json CRLF handling (<a
href="https://redirect.github.com/j178/prek/pull/2210">#2210</a>)</li>
<li>Handle missing blobs in diff snapshots (<a
href="https://redirect.github.com/j178/prek/pull/2211">#2211</a>)</li>
<li>Ignore coursier channel from working repo (<a
href="https://redirect.github.com/j178/prek/pull/2202">#2202</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
<h2>Install prek 0.4.5</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.5</h2>
<p>Released on 2026-06-15.</p>
<h3>✨Highlights</h3>
<p>0.4.5 completes <code>prek</code>'s pre-commit language coverage.
With R, Conda, Perl,
and coursier now supported, <code>prek</code> supports every language
available in
pre-commit, plus <code>prek</code>-only modern languages such as Bun and
Deno.</p>
<p>This is full feature parity with pre-commit. The last major
compatibility gap
is closed, and <code>prek</code> is now on the path to 1.0.</p>
<h3>💚 Sponsorship</h3>
<p>If <code>prek</code> saves time for you or your team, please consider
sponsoring the
project on <a href="https://github.com/sponsors/j178">GitHub
Sponsors</a>. It helps keep
new features, performance work, and maintenance moving.</p>
<h3>Enhancements</h3>
<ul>
<li>Add <code>Perl</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2201">#2201</a>)</li>
<li>Add <code>R</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2206">#2206</a>)</li>
<li>Add <code>Conda</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2203">#2203</a>)</li>
<li>Add <code>coursier</code> language support (<a
href="https://redirect.github.com/j178/prek/pull/2194">#2194</a>)</li>
<li>Add group filters to list (<a
href="https://redirect.github.com/j178/prek/pull/2152">#2152</a>)</li>
<li>Remove legacy repo path support (<a
href="https://redirect.github.com/j178/prek/pull/2150">#2150</a>)</li>
<li>Skip cloning fully filtered remote repos (<a
href="https://redirect.github.com/j178/prek/pull/2151">#2151</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Avoid building JSON trees in syntax hooks (<a
href="https://redirect.github.com/j178/prek/pull/2156">#2156</a>)</li>
<li>Scan mixed line endings without line vector (<a
href="https://redirect.github.com/j178/prek/pull/2160">#2160</a>)</li>
<li>Skip file scan for always-run no-filename hooks (<a
href="https://redirect.github.com/j178/prek/pull/2155">#2155</a>)</li>
<li>Use fixed buffer for EOF scan (<a
href="https://redirect.github.com/j178/prek/pull/2163">#2163</a>)</li>
<li>Use fixed buffer for private key scan (<a
href="https://redirect.github.com/j178/prek/pull/2164">#2164</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix pretty-format-json CRLF handling (<a
href="https://redirect.github.com/j178/prek/pull/2210">#2210</a>)</li>
<li>Handle missing blobs in diff snapshots (<a
href="https://redirect.github.com/j178/prek/pull/2211">#2211</a>)</li>
<li>Ignore coursier channel from working repo (<a
href="https://redirect.github.com/j178/prek/pull/2202">#2202</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/j178"><code>@​j178</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/bb3108283fd4aab0d9eb59f23098e0c05a96cdbe"><code>bb31082</code></a>
Update README.md</li>
<li><a
href="https://github.com/j178/prek/commit/fa4e2dc060eccac3c2521ec7bf4af1272c5d6205"><code>fa4e2dc</code></a>
Bump version to 0.4.5 (<a
href="https://redirect.github.com/j178/prek/issues/2221">#2221</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/e9336fa724b8a99b3a21fd60eb0849cd731153ef"><code>e9336fa</code></a>
Add R language support (<a
href="https://redirect.github.com/j178/prek/issues/2206">#2206</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/97a5a15701d3691287e4f969a2a2f421d1501a46"><code>97a5a15</code></a>
Update Rust crate which to v8.0.3 (<a
href="https://redirect.github.com/j178/prek/issues/2219">#2219</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/20a519aa2aa4add7e70dfbb2ff743cd1f35e25f3"><code>20a519a</code></a>
Update Rust crate ignore to v0.4.26 (<a
href="https://redirect.github.com/j178/prek/issues/2218">#2218</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/88f0e2bd8a7d02be7fb19fcd17e1e8db79b8b0bc"><code>88f0e2b</code></a>
Update dependency uv to v0.11.19 (<a
href="https://redirect.github.com/j178/prek/issues/2214">#2214</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/7bd43000679b33e2b947f453436237dae062af70"><code>7bd4300</code></a>
Update GitHub Actions to v7 (<a
href="https://redirect.github.com/j178/prek/issues/2220">#2220</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/48ed5cc2838066d71278dd887dee595c32085be2"><code>48ed5cc</code></a>
Update Rust crate async_zip to 0.0.18 (<a
href="https://redirect.github.com/j178/prek/issues/2217">#2217</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/257e98a429e96f89a4d965ad28568cba77ca33c2"><code>257e98a</code></a>
Update pre-commit to v1.47.2 (<a
href="https://redirect.github.com/j178/prek/issues/2216">#2216</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/0c0460241a13b9ac519e1abd3a0a8a3ad60d4d2f"><code>0c04602</code></a>
Update GitHub Actions (<a
href="https://redirect.github.com/j178/prek/issues/2215">#2215</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.4.4...v0.4.5">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 00:00:30 -04:00
dependabot[bot] 3c1b79989a Bump node from fb71d01 to 156b55f in the docker-base-image-digests group (#1075)
Bumps the docker-base-image-digests group with 1 update: node.

Updates `node` from `fb71d01` to `156b55f`


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=node&package-manager=docker&previous-version=24-alpine&new-version=24-alpine)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 00:00:22 -04:00
dependabot[bot] e41c1d4e8e Bump python from 3.14.5-slim to 3.14.6-slim (#1076)
Bumps python from 3.14.5-slim to 3.14.6-slim.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.14.5-slim&new-version=3.14.6-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-21 00:00:13 -04:00
Hrachya ShaginyanandZo Bot ec7e3482bb use a stable hash for the Booklore options cache key (#1079)
`_get_booklore_cache_key` returned
`f"{base_url}|{username}|{hash(password)}"`. Python's built-in `hash()`
is randomized per process (`PYTHONHASHSEED`), so the cache key for the
same Booklore credentials changed between every worker process and every
restart. If the dashboard was opened by a worker that landed on a
different seed than the worker that warmed the cache, the
`_BOOKLORE_OPTIONS_CACHE.get("key") == cache_key` check would miss on
every lookup, forcing a fresh `booklore_login` API call each time.

Switch to `hashlib.sha256(password.encode()).hexdigest()` —
deterministic across processes and restarts. SHA-256 is overkill for a
cache key, but matching the existing convention (`hashlib.sha1` is used
elsewhere in the codebase) is what we want here.

The password is already in memory (it comes from the request body /
`config.get`), so this doesn't introduce a new secret-handling concern.

Co-authored-by: Zo Bot <github-automation@zo.computer>
2026-06-20 23:59:56 -04:00
dependabot[bot] 05cd384efc Bump the python-deps group with 3 updates (#1073)
Bumps the python-deps group with 3 updates:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase),
[basedpyright](https://github.com/detachhead/basedpyright) and
[pytest](https://github.com/pytest-dev/pytest).

Updates `seleniumbase` from 4.49.12 to 4.49.13
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.13 - Refresh Python dependencies</h2>
<h2>Refresh Python dependencies</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1cfc9c241fa4e8065a61ea1124f374257e464af4">Refresh
Python dependencies</a>
-- Refresh <code>filelock</code>, <code>pytest</code>, and
<code>pyotp</code>.</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Refresh Python dependencies by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4390">seleniumbase/SeleniumBase#4390</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.12...v4.49.13">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.12...v4.49.13</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/daa6847905136b1e62a44837a1a03c7b3ca415d2"><code>daa6847</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4390">#4390</a>
from seleniumbase/refresh-python-dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/07722ce8bb401174ac1b7d3e0bfc3a476ea2d4d8"><code>07722ce</code></a>
Version 4.39.13</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1cfc9c241fa4e8065a61ea1124f374257e464af4"><code>1cfc9c2</code></a>
Refresh Python dependencies</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.12...v4.49.13">compare
view</a></li>
</ul>
</details>
<br />

Updates `basedpyright` from 1.39.7 to 1.39.8
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/fab7323c03bfa17db61cf63457beee9e484fde80"><code>fab7323</code></a>
1.39.8</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/c685372fd5da030a7c922b65ef8ecfd1e1cf7265"><code>c685372</code></a>
Avoid auto f-string conversion for raw strings</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/a55c2a4ddc65230bde700c32677d62e4e7c6586b"><code>a55c2a4</code></a>
docs: document typeCheckingMode off behavior</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/61b9817de80a927395ce2315a2e34c663ac43664"><code>61b9817</code></a>
fix: clarify implicit abstract class diagnostic</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/7dd1aafafd74d3c9c07a2a287295c5dafa073f38"><code>7dd1aaf</code></a>
fix default value in <code>pythonPlatform</code> documentation, which
differs from upstream</li>
<li>See full diff in <a
href="https://github.com/detachhead/basedpyright/compare/v1.39.7...v1.39.8">compare
view</a></li>
</ul>
</details>
<br />

Updates `pytest` from 9.0.3 to 9.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pytest-dev/pytest/releases">pytest's
releases</a>.</em></p>
<blockquote>
<h2>9.1.0</h2>
<h1>pytest 9.1.0 (2026-06-13)</h1>
<h2>Removals and backward incompatible breaking changes</h2>
<ul>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14533">#14533</a>:
When using <code>--doctest-modules</code>, autouse fixtures with
<code>module</code>, <code>package</code> or <code>session</code> scope
that are defined inline in Python test modules (not plugins or
conftests) will now possibly execute twice.</p>
<p>If this is undesirable, move the fixture definition to a
<code>conftest.py</code> file if possible.</p>
<p>Technical explanation for those interested:
When using <!-- raw HTML omitted -->--doctest-modules<!-- raw HTML
omitted -->, pytest possibly collects Python modules twice, once as
<code>pytest.Module</code> and once as a <code>DoctestModule</code>
(depending on the configuration).
Due to improvements in pytest's fixture implementation, if e.g. the
<code>DoctestModule</code> collects a fixture, it is now visible to it
only, and not to the <code>Module</code>.
This means that both need to register the fixtures independently.</p>
</li>
</ul>
<h2>Deprecations (removal in next major release)</h2>
<ul>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/10819">#10819</a>:
Added a deprecation warning for class-scoped fixtures defined as
instance methods (without <code>@classmethod</code>). Such fixtures set
attributes on a different instance than the test methods use, leading to
unexpected behavior. Use <code>@classmethod</code> decorator instead --
by <code>yastcher</code>.</p>
<p>See <code>10819</code> and <code>14011</code>.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/12882">#12882</a>:
Calling <code>request.getfixturevalue()
&lt;pytest.FixtureRequest.getfixturevalue&gt;</code> during teardown to
request a fixture that was not already requested is now deprecated and
will become an error in pytest 10.</p>
<p>See <code>dynamic-fixture-request-during-teardown</code> for
details.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13409">#13409</a>:
Using non-<code>~collections.abc.Collection</code> iterables (such as
generators, iterators, or custom iterable objects) for the
<code>argvalues</code> parameter in <code>@pytest.mark.parametrize
&lt;pytest.mark.parametrize ref&gt;</code> and
<code>metafunc.parametrize &lt;pytest.Metafunc.parametrize&gt;</code> is
now deprecated.</p>
<p>These iterables get exhausted after the first iteration,
leading to tests getting unexpectedly skipped in cases such as running
<code>pytest.main()</code> multiple times,
using class-level parametrize decorators,
or collecting tests multiple times.</p>
<p>See <code>parametrize-iterators</code> for details and
suggestions.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/13946">#13946</a>:
The private <code>config.inicfg</code> attribute is now deprecated.
Use <code>config.getini() &lt;pytest.Config.getini&gt;</code> to access
configuration values instead.</p>
<p>See <code>config-inicfg</code> for more details.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14004">#14004</a>:
Passing <code>baseid</code> to <code>~pytest.FixtureDef</code> or
<code>nodeid</code> strings to fixture registration APIs is now
deprecated. These are internal pytest APIs that are used by some
plugins.</p>
<p>Use the <code>node</code> parameter instead for fixture scoping. This
enables more robust node-based
matching instead of string prefix matching.
If you've used <code>nodeid=None</code>, pass <code>node=session</code>
instead.</p>
<p>This will be removed in pytest 10.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14335">#14335</a>:
The method of configuring hooks using markers, deprecated since pytest
7.2, is now scheduled to be removed in pytest 10.
See <code>hook-markers</code> for more details.</p>
</li>
<li>
<p><a
href="https://redirect.github.com/pytest-dev/pytest/issues/14434">#14434</a>:
The <code>--pastebin</code> option is now deprecated.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pytest-dev/pytest/commit/b2522cf0b11fb33ecc1f4895fa1dffbb9252a63d"><code>b2522cf</code></a>
Prepare release version 9.1.0</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/368d2fca78e86ac79ec269bb078fcb1259a94fed"><code>368d2fc</code></a>
[refactor] Tighten <code>SetComparisonFunction</code> to
<code>Iterator[str]</code> (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14587">#14587</a>)</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/ff77cd8b66b43a88c26ca54384bbcab72d079497"><code>ff77cd8</code></a>
[refactor] Make base assertion comparisons return an iterator instead of
a li...</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/0d8491a4ecf971800de0479ef55c7f5292c54937"><code>0d8491a</code></a>
build(deps): Bump actions/stale from 10.2.0 to 10.3.0</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/4a809d9c892f6abb5ba92b77b06f1dd878f4660a"><code>4a809d9</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14568">#14568</a>
from pytest-dev/register-fixture</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/5dfa38541becfb77d0f52cac4cc8cce71849ab61"><code>5dfa385</code></a>
Fix recursion traceback test to cover all styles (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14582">#14582</a>)</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/f52ff0c1778c15038cf2bbb00b7668dac674cc26"><code>f52ff0c</code></a>
Add <code>pytest.register_fixture</code></li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/a8ac094e80df788aec844794170b126eab0be7a4"><code>a8ac094</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14567">#14567</a>
from pytest-dev/more-visibility-deprecate</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/e5620cd21ec62f5a5f9a5141a3c76fb3953729b6"><code>e5620cd</code></a>
[pre-commit.ci] pre-commit autoupdate (<a
href="https://redirect.github.com/pytest-dev/pytest/issues/14577">#14577</a>)</li>
<li><a
href="https://github.com/pytest-dev/pytest/commit/2ce9c6d94eb691ea4da7f91f330602cbb67a6daf"><code>2ce9c6d</code></a>
Merge pull request <a
href="https://redirect.github.com/pytest-dev/pytest/issues/14540">#14540</a>
from minbang930/fix-14533-doctest-module-fixtures</li>
<li>Additional commits viewable in <a
href="https://github.com/pytest-dev/pytest/compare/9.0.3...9.1.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 00:29:33 -04:00
dependabot[bot] 880cc4a299 Bump seleniumbase from 4.49.10 to 4.49.12 in the python-deps group (#1070)
Bumps the python-deps group with 1 update:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase).

Updates `seleniumbase` from 4.49.10 to 4.49.12
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.12 - CDP Mode: Patch 116</h2>
<h2>CDP Mode: Patch 116</h2>
<ul>
<li><a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4389/commits/f87cf4f13a0e19fc360d7e8b98037dc79ec64da1">Add
missing await for async method call in CDP Mode</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4388">seleniumbase/SeleniumBase#4388</a>
-- (Applies to setting <code>ad_block=True</code> in CDP Mode)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 116 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4389">seleniumbase/SeleniumBase#4389</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.11...v4.49.12">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.11...v4.49.12</a></p>
<h2>4.49.11 - CDP Mode: Patch 115</h2>
<h2>CDP Mode: Patch 115</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/4207eebedeb32eb2d7c13145c70d50680b6f5fbb">Update
MyCDP</a>
-- (Note that all CDP calls go through <code>MyCDP</code>)</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d2a57ef2c4a2a8b706093c588c7e9da78782611f">Update
CDP Mode</a>
-- Added a custom message option for all assertions
-- Added more time for the ad-blocker to take effect</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 115 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4385">seleniumbase/SeleniumBase#4385</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.10...v4.49.11">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.10...v4.49.11</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/18b058837f4645588ec76eb859f57104aca78b95"><code>18b0588</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4389">#4389</a>
from seleniumbase/cdp-mode-patch-116</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7a71fea3f9d3419cfbe7dff7d630b59d53851ac2"><code>7a71fea</code></a>
Version 4.49.12</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f87cf4f13a0e19fc360d7e8b98037dc79ec64da1"><code>f87cf4f</code></a>
Add missing <code>await</code> for async method call</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c9b450433a5750426a1143250ad7e0c24ed3ffa4"><code>c9b4504</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4385">#4385</a>
from seleniumbase/cdp-mode-patch-115</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/daefe6f4ff1bf20408ba666a1f07347a81a9f6b8"><code>daefe6f</code></a>
Version 4.49.11</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/fc721de65c74b42bca13b89bec411aa90ffe55bb"><code>fc721de</code></a>
Update CDP Mode examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/eb063047cc6e8ffd4a7fca8ff3b07701d8b16037"><code>eb06304</code></a>
Update an optional Python dependency</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/4207eebedeb32eb2d7c13145c70d50680b6f5fbb"><code>4207eeb</code></a>
Update MyCDP</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/d2a57ef2c4a2a8b706093c588c7e9da78782611f"><code>d2a57ef</code></a>
Update CDP Mode</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.10...v4.49.12">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=seleniumbase&package-manager=uv&previous-version=4.49.10&new-version=4.49.12)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-17 14:26:40 -04:00
CaliBrain e9668371f7 Fix IRC caching (#1072) 2026-06-17 14:25:31 -04:00
CaliBrain d55e42fbc6 Add torrent fix for untrusted URL (#1071) 2026-06-17 13:46:51 -04:00
dependabot[bot] ade4878cfd Bump the python-deps group with 2 updates (#1068)
Bumps the python-deps group with 2 updates:
[seleniumbase](https://github.com/seleniumbase/SeleniumBase) and
[ruff](https://github.com/astral-sh/ruff).

Updates `seleniumbase` from 4.49.9 to 4.49.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.10 - CDP Mode: Patch 114</h2>
<h2>CDP Mode: Patch 114</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/86f67c312b02c308c90e823080f2c6a98cb0986a">Update
CDP Mode</a>
-- Improve error-handling for various edge-cases
-- Make sure all CDP Mode methods can be called via
<code>sb.METHOD</code> (rather than <code>sb.cdp.METHOD</code>)</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0588e9b5470deb0406b7f9584be93dfb00453979">Optimize
imports in browser_launcher.py</a>
-- A few of the big imports are not always needed</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/205bf88f0c58c400ed900fd0f9cdf91ba1200e5c">Update
examples</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/07ce62e9516138ec1a7c3e41529efc0690ff7bf3">Update
the docs</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 114 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4381">seleniumbase/SeleniumBase#4381</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.9...v4.49.10">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.9...v4.49.10</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/8204d89e43855801be6ab0bfbb572e015ce3502d"><code>8204d89</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4381">#4381</a>
from seleniumbase/cdp-mode-patch-114</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/598917507da14acfaf2339acd377fe6b8f643a53"><code>5989175</code></a>
Version 4.49.10</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/07ce62e9516138ec1a7c3e41529efc0690ff7bf3"><code>07ce62e</code></a>
Update the docs</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/205bf88f0c58c400ed900fd0f9cdf91ba1200e5c"><code>205bf88</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0588e9b5470deb0406b7f9584be93dfb00453979"><code>0588e9b</code></a>
Optimize imports in browser_launcher.py</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/86f67c312b02c308c90e823080f2c6a98cb0986a"><code>86f67c3</code></a>
Update CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c7d6a6d192f6782cb7388e84290a0c96106d15c2"><code>c7d6a6d</code></a>
Update the ReadMe</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1f22eb4bcc3478ca791ba06bfde1ff8a097d1f6d"><code>1f22eb4</code></a>
Update a presentation</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3ef7b314900560624f8be90bd4db232688fcb267"><code>3ef7b31</code></a>
Update Google examples</li>
<li>See full diff in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.9...v4.49.10">compare
view</a></li>
</ul>
</details>
<br />

Updates `ruff` from 0.15.16 to 0.15.17
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.17</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-11.</p>
<h3>Preview features</h3>
<ul>
<li>Allow human-readable names in suppression comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25614">#25614</a>)</li>
<li>Fix handling of <code>ignore</code> comments within a
<code>disable</code>/<code>enable</code> pair (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25845">#25845</a>)</li>
<li>Prioritize human-readable names in CLI output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25869">#25869</a>)</li>
<li>Respect diagnostic start and parent ranges and trailing comments in
<code>ruff:ignore</code> suppressions (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25673">#25673</a>)</li>
<li>[<code>flake8-async</code>] Add <code>trio.as_safe_channel</code> to
safe decorators (<code>ASYNC119</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25775">#25775</a>)</li>
<li>[<code>flake8-pytest-style</code>] Also check
<code>pytest_asyncio</code> fixtures (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25375">#25375</a>)</li>
<li>[<code>ruff</code>] Ban <code>pytest</code> autouse fixtures
(<code>RUF076</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25477">#25477</a>)</li>
<li>[<code>pyupgrade</code>] Add <code>from __future__ import
annotations</code> automatically (<code>UP007</code>,
<code>UP045</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23259">#23259</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix diagnostic when <code>ruff:enable</code> or
<code>ruff:disable</code> appears where <code>ruff:ignore</code> is
expected (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25700">#25700</a>)</li>
<li>[<code>pyupgrade</code>] Preserve leading empty literals to avoid
syntax errors (<code>UP032</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25491">#25491</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pytest-style</code>] Clarify diagnostic message for
single parameters (<code>PT007</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25592">#25592</a>)</li>
<li>[<code>numpy</code>] Drop autofix for <code>np.in1d</code>
(<code>NPY201</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25612">#25612</a>)</li>
<li>[<code>pylint</code>] Exempt Python version comparisons
(<code>PLR2004</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25743">#25743</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Reserve AST <code>Vec</code>s with correct capacity for common cases
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/25451">#25451</a>)</li>
</ul>
<h3>Formatter</h3>
<ul>
<li>Preserve whitespace for Quarto cell option comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25641">#25641</a>)</li>
</ul>
<h3>CLI</h3>
<ul>
<li>Allow rule names in <code>ruff rule</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25640">#25640</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Fix playground diagnostics scrollbars (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25642">#25642</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/SuryanshSS1011"><code>@​SuryanshSS1011</code></a></li>
<li><a
href="https://github.com/anishgirianish"><code>@​anishgirianish</code></a></li>
<li><a
href="https://github.com/romero-deshaw"><code>@​romero-deshaw</code></a></li>
<li><a
href="https://github.com/karlhillx"><code>@​karlhillx</code></a></li>
<li><a href="https://github.com/carljm"><code>@​carljm</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.17</h2>
<p>Released on 2026-06-11.</p>
<h3>Preview features</h3>
<ul>
<li>Allow human-readable names in suppression comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25614">#25614</a>)</li>
<li>Fix handling of <code>ignore</code> comments within a
<code>disable</code>/<code>enable</code> pair (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25845">#25845</a>)</li>
<li>Prioritize human-readable names in CLI output (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25869">#25869</a>)</li>
<li>Respect diagnostic start and parent ranges and trailing comments in
<code>ruff:ignore</code> suppressions (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25673">#25673</a>)</li>
<li>[<code>flake8-async</code>] Add <code>trio.as_safe_channel</code> to
safe decorators (<code>ASYNC119</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25775">#25775</a>)</li>
<li>[<code>flake8-pytest-style</code>] Also check
<code>pytest_asyncio</code> fixtures (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25375">#25375</a>)</li>
<li>[<code>ruff</code>] Ban <code>pytest</code> autouse fixtures
(<code>RUF076</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25477">#25477</a>)</li>
<li>[<code>pyupgrade</code>] Add <code>from __future__ import
annotations</code> automatically (<code>UP007</code>,
<code>UP045</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/23259">#23259</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix diagnostic when <code>ruff:enable</code> or
<code>ruff:disable</code> appears where <code>ruff:ignore</code> is
expected (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25700">#25700</a>)</li>
<li>[<code>pyupgrade</code>] Preserve leading empty literals to avoid
syntax errors (<code>UP032</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25491">#25491</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pytest-style</code>] Clarify diagnostic message for
single parameters (<code>PT007</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25592">#25592</a>)</li>
<li>[<code>numpy</code>] Drop autofix for <code>np.in1d</code>
(<code>NPY201</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25612">#25612</a>)</li>
<li>[<code>pylint</code>] Exempt Python version comparisons
(<code>PLR2004</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25743">#25743</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Reserve AST <code>Vec</code>s with correct capacity for common cases
(<a
href="https://redirect.github.com/astral-sh/ruff/pull/25451">#25451</a>)</li>
</ul>
<h3>Formatter</h3>
<ul>
<li>Preserve whitespace for Quarto cell option comments (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25641">#25641</a>)</li>
</ul>
<h3>CLI</h3>
<ul>
<li>Allow rule names in <code>ruff rule</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25640">#25640</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Fix playground diagnostics scrollbars (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25642">#25642</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/SuryanshSS1011"><code>@​SuryanshSS1011</code></a></li>
<li><a
href="https://github.com/anishgirianish"><code>@​anishgirianish</code></a></li>
<li><a
href="https://github.com/romero-deshaw"><code>@​romero-deshaw</code></a></li>
<li><a
href="https://github.com/karlhillx"><code>@​karlhillx</code></a></li>
<li><a href="https://github.com/carljm"><code>@​carljm</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/ruff/commit/7c645a9a1be8258b9f9e005208a55a0b7e8e18f0"><code>7c645a9</code></a>
Bump 0.15.17 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25872">#25872</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/f381eb1d54997cfbfa6f63c15dd2d760f70e85e1"><code>f381eb1</code></a>
Prioritize human-readable names in CLI output (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25869">#25869</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/b9b4546ad27d8fd12acc979e312a3ee25ef8ac4f"><code>b9b4546</code></a>
Minor workflow simplification (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25870">#25870</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/1e77ba02570bbe4952f7cf0e4ebb97b8b4e6e58d"><code>1e77ba0</code></a>
[ty] Move <code>PreformattedBlockScanner</code> to format-agnostic
location. (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25856">#25856</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/6f2b772285aa478e8aee3f4b54dfa9ce903a0ce1"><code>6f2b772</code></a>
[ty] Preserve nominal type of enum.property instances (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25849">#25849</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/be4777c8766a38d405a69948989cdfa2674adaae"><code>be4777c</code></a>
[ty] Fix site-package error when multiple versions of pythons are
installed i...</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/53f6ff7200983a67778fcba7106019d2615846f0"><code>53f6ff7</code></a>
Allow human-readable names in suppression comments (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25614">#25614</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/67403254192f3541bd7e1027c8f1805cf7a9c2be"><code>6740325</code></a>
[ty] Restrict uncached raw signature access (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25866">#25866</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/970b1bf4a4d83359c9e28cad5f127ebbd6769682"><code>970b1bf</code></a>
Auto-update snapshots when syncing typeshed (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25841">#25841</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/0785793750fd6c74124a189259822f1a28eb5c13"><code>0785793</code></a>
Fix handling of <code>ignore</code> comments within a
<code>disable</code>/<code>enable</code> pair (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25845">#25845</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.15.16...0.15.17">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-15 00:30:58 -04:00
aba1a68dda Backport bug fixes from NemesisHubris/litfinder (addresses #999, #956, #1010, #1021, #1025, #1040) (#1066)
## Backport bug fixes from `NemesisHubris/litfinder`

Forwards a curated set of bug fixes from
[NemesisHubris/litfinder](https://github.com/NemesisHubris/litfinder) —
a community fork of this project — that address open issues here. All
commits preserve original authorship via `git cherry-pick`; this PR is a
backport rather than original work. Each fix has been reviewed locally,
lint/format-cleaned to match this repo's existing ruff config, and
verified with the test suite. Rebrand strings, license switches, and
features have been deliberately excluded.

### Upstream issues addressed

- **#999** — Mirror URLs with query params no longer break search
requests (strip query string/fragment in `normalize_http_url`)
- **#956** — Apprise notifications now respect the configured proxy
(proxy env vars injected before dispatch)
- **#1025** — rTorrent: separate `RTORRENT_AUDIOBOOK_LABEL` setting,
falls back to book label if unset
- **#1010** — Stop button in Activity no longer makes the panel
disappear (snapshot refresh on cancel)
- **#1021** — Anna's Archive slow-download countdown now caps retries
instead of looping forever
- **#1040** — Empty destination directory cleaned up when write probe
fails
- **PR #1031** — Language detection from Anna's Archive distant path
when listing metadata is missing

### Additional fixes (no open issue but clear bugs)

- **fix: Python 2 `except` syntax across 27 files** — `except X, Y:` is
a SyntaxError in Python 3 and prevents affected modules from importing
at runtime. Mechanical sweep to `except (X, Y):`.
- **fix(abb): info hash validation with magnet fallback** — adds
SHA-1/SHA-256 hex validation on extracted info hashes; falls back to
scanning the full page for a magnet link (e.g. posted in comments) when
the table value is malformed. Also extends the exact-phrase fallback to
manual queries and defaults the ABB listing language to `en` when
missing, preventing valid results from being hidden by the language
filter. Includes a small test-fixture fix (`test(abb): use valid hex
info hashes in scraper test fixtures`) since the existing fixtures used
non-hex placeholders that the new validation correctly rejects.
- **fix: Anna's Archive title parser** — handles nested edition spans
and filters `lgli` catalog descriptor entries (e.g. "Book/Online Audio")
that were polluting search results.

### Deliberately not included

- LitFinder rebranding (UI strings, Apprise app ID, logo). The `fix:
three upstream bugs` commit (#999/#956/#1025) was cherry-picked with
Apprise app-id, description, and logo-URL strings reverted from
"LitFinder" back to "Shelfmark"; noted in the commit body.
- Features from the LitFinder fork (multi-variant title search,
multi-book flat-folder grouping, fuzzy text matching, "Leave in Place"
output handler, admin display name, custom-source plugin system). These
are larger behavior changes that each warrant their own focused review —
happy to send any of them separately if of interest.
- LitFinder-specific test environment and CI infrastructure.

### Verification

- Backend: **1879 passed**, 96 skipped (1 preexisting failure on
`seleniumbase`-dependent test in local venv; runs fine in the standard
Docker image with the `browser` extra)
- Lint, format, dead-code: all clean against this repo's existing
ruff/vulture config
- One follow-up cleanup commit (`style: ruff lint and format fixes for
ported commits`) brings the cherry-picked code into compliance with this
repo's ruff settings — no behavior changes there

### Etiquette / credit

Per-commit authorship preserved by cherry-pick. The only edits to the
original commits are:
- `fix: three upstream bugs` — Apprise rebrand strings reverted to
"Shelfmark" (noted in commit body, original author retained as
`Co-Authored-By` via cherry-pick)
- One follow-up `style:` commit for ruff config alignment

Big thanks to [@NemesisHubris](https://github.com/NemesisHubris) for the
original work in LitFinder; this PR exists to make sure these fixes
reach Shelfmark's wider user base. Happy to revise scope, split into
smaller PRs, or split off the Py2 cleanup separately if that's
preferable.

---------

Co-authored-by: NemesisHubris <155838970+NemesisHubris@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-15 00:28:43 -04:00
bullitt168 6231678c28 fix: "No files found." check produces false positives when AA returns results alongside that string (#1067)
## Problem

Searching Anna's Archive with multiple format filters (e.g. `epub`,
`mobi`, `pdf`, …) combined with a language filter (`lang=de`) and a
specific title produces a response that **contains both a full results
table and a `\"No files found.\"` span** in a separate section of the
page.

The previous code performed a naïve substring check on the raw HTML
before parsing:

```python
if "No files found." in html:
    logger.info("No books found for query: %s", query)
    return []
```

When Anna's Archive renders a page that has, e.g., results for one
content type but no results for another sub-filter, it emits a `<span
class="font-bold">No files found.</span>` in the empty sub-section while
the main results table is fully populated (650+ entries in the tested
case). The early return discards all those results, making Shelfmark
appear unable to find anything on Anna's Archive.

Reported upstream as: https://github.com/calibrain/shelfmark/issues/1042

## Root cause

The string `"No files found."` appears in multiple places on an AA
search results page. It is not a reliable signal that the entire query
returned zero results — only that *some* filtered sub-section is empty.

## Fix

Parse the HTML into BeautifulSoup first and look for the results
`<table>`. Only if no table is present does it make sense to fall back
to the string check:

```python
soup = BeautifulSoup(_html_response_text(html), "html.parser")
tbody = soup.find("table")

if tbody is None:
    if "No files found." in html:
        logger.info("No books found for query: %s", query)
        return []
    logger.warning("No results table found for query: %s", query)
    msg = "No books found. Please try another query."
    raise RuntimeError(msg)
```

This preserves both existing behaviours:
- Genuine empty results (no table + "No files found." present) → return
`[]`
- Unexpected response structure (no table, no "No files found." either)
→ raise `RuntimeError`

And fixes the false-positive case (table present + "No files found." in
another section) → proceed normally and parse the table.

## Testing

Verified on a self-hosted Shelfmark v1.3.0 instance against
`annas-archive.gl`:

- Query: `"Reise zum Mittelpunkt der Erde"` + `lang=de` + all supported
ebook formats
- Before fix: `search_books()` returned `[]` immediately
- After fix: `search_books()` returned 6 matching German epub/mobi
results

The fix is a pure restructuring — no logic is added or removed, only the
order of operations changes.
2026-06-14 22:45:36 -04:00
dependabot[bot] b5acbc1209 Bump node from 2bdb65e to fb71d01 in the docker-base-image-digests group (#1061)
Bumps the docker-base-image-digests group with 1 update: node.

Updates `node` from `2bdb65e` to `fb71d01`


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=node&package-manager=docker&previous-version=24-alpine&new-version=24-alpine)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-14 01:41:02 -04:00
dependabot[bot] b0df608a53 Bump the python-deps group with 2 updates (#1064)
Bumps the python-deps group with 2 updates:
[tqdm](https://github.com/tqdm/tqdm) and
[seleniumbase](https://github.com/seleniumbase/SeleniumBase).

Updates `tqdm` from 4.68.1 to 4.68.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tqdm/tqdm/releases">tqdm's
releases</a>.</em></p>
<blockquote>
<h2>tqdm v4.68.2 stable</h2>
<ul>
<li>revert accidental change to <code>ascii</code> default (fixes <a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a>)
<ul>
<li><code>UnicodeEncodeError: 'charmap' codec can't encode characters in
position 6-7: character maps to &lt;undefined&gt;</code> can be fixed by
installing <code>tqdm!=4.68.0,!=4.68.1</code></li>
</ul>
</li>
<li>misc docs updates
<ul>
<li>fix links</li>
<li>replace stray <code>rst</code> -&gt; <code>md</code> syntax</li>
<li>consistent &quot;progress bar&quot; terminology (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1737">#1737</a>)</li>
</ul>
</li>
<li>tests: fix coverage (fixes <a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tqdm/tqdm/commit/4b3395272d66a00d7d4eebec5a4e19ae679aa95d"><code>4b33952</code></a>
revert accidental change to <code>tqdm(ascii)</code> default</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/b10848f8aaece089c70590425fd4262a68beb57f"><code>b10848f</code></a>
docs: fix links</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/85b62dd5fc5f1cc83f37802312d5d71a1a970e86"><code>85b62dd</code></a>
docs: replace stray rst -&gt; md</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/d2fb04af6fbf49501dce9cc82f0ea8971924dee7"><code>d2fb04a</code></a>
docs: mention OpenAI sponsorship</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/85940f9d17a679f9189a8346b05c0580f313f69f"><code>85940f9</code></a>
docs: consistent progress bar terminology</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/9dbb36be49a91bb86b15883e0d8c6ad1d3fb4aa2"><code>9dbb36b</code></a>
tests: fix coverage</li>
<li>See full diff in <a
href="https://github.com/tqdm/tqdm/compare/v4.68.1...v4.68.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.49.7 to 4.49.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.9 - CDP Mode: Patch 113</h2>
<h2>CDP Mode: Patch 113</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/b519bf97b34f4d84a7492cf89ce6b441f7ac0516">Add
functionality for handling downloads in CDP Mode</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4376">seleniumbase/SeleniumBase#4376</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/351c3c94964661e203292bab08e815c5f3cbbb05">Add
method for extracting all links in CDP Mode</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4377">seleniumbase/SeleniumBase#4377</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/08a439413d62c3033a007ae52f332fd9382eaea5">Allow
custom messages with failed assertions in CDP Mode</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3452e83fdb7593cf98c2f190d1658377e279394d">Update
the docs</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1dda14cd8f68aa8e88e6a6430980a014924e9715">Update
examples</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/81321f8d21095787d71ce9c5aa0096ea90d1b060">Refresh
Python dependencies</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 113 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4378">seleniumbase/SeleniumBase#4378</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.8...v4.49.9">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.8...v4.49.9</a></p>
<h2>4.49.8 - The Great Refactor</h2>
<h2>The Great Refactor</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/7f937365d93263cc2b19f8501e76bb27597b20df">Update
the self-hosted dashboard</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4372">seleniumbase/SeleniumBase#4372</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/532cc63228ed520d1df714d072fd2f01ac4fc9bf">Refactor
code, examples, and docs</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4370">seleniumbase/SeleniumBase#4370</a>
-- This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4371">seleniumbase/SeleniumBase#4371</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/61bfb23b2dddafc9f5725a7c2168d41b30b05cc6">Refresh
Python dependencies</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>The Great Refactor by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4373">seleniumbase/SeleniumBase#4373</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.7...v4.49.8">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.7...v4.49.8</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e12db778079b4e7d0e871d8a6e1184d8ffa78d50"><code>e12db77</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4378">#4378</a>
from seleniumbase/cdp-mode-patch-113</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/838147d8e3a91f2dbdae7c2714e5f46b3b6ecd3c"><code>838147d</code></a>
Version 4.49.9</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/81321f8d21095787d71ce9c5aa0096ea90d1b060"><code>81321f8</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3452e83fdb7593cf98c2f190d1658377e279394d"><code>3452e83</code></a>
Update the docs</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1dda14cd8f68aa8e88e6a6430980a014924e9715"><code>1dda14c</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/08a439413d62c3033a007ae52f332fd9382eaea5"><code>08a4394</code></a>
Allow custom messages with failed assertions in CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/351c3c94964661e203292bab08e815c5f3cbbb05"><code>351c3c9</code></a>
Add method for extracting all links in CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/b519bf97b34f4d84a7492cf89ce6b441f7ac0516"><code>b519bf9</code></a>
Add functionality for handling downloads in CDP Mode</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cb1ad4f6469e6774c6057c382b9e35ce2aefdab1"><code>cb1ad4f</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4373">#4373</a>
from seleniumbase/the-great-refactor</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/6d789dd65f3f3f0334c44df0ad7d429943e53301"><code>6d789dd</code></a>
Version 4.49.8</li>
<li>Additional commits viewable in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.7...v4.49.9">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-14 01:40:40 -04:00
dependabot[bot] 68e4e6120e Bump @types/node from 25.9.2 to 25.9.3 in /src/frontend in the npm-deps group (#1063)
Bumps the npm-deps group in /src/frontend with 1 update:
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).

Updates `@types/node` from 25.9.2 to 25.9.3
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=25.9.2&new-version=25.9.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-14 01:40:31 -04:00
CaliBrain c64c2d374a Make IRC less spammy and require a bot name for conversatons (#1065)
First step towards fixing the friction created by shelfmark in #997
2026-06-14 01:40:09 -04:00
CaliBrain 75c0b0c33a Update dependabot.yml (#1060) 2026-06-14 01:19:08 -04:00
dependabot[bot] d695b636f0 Bump the npm-deps group in /src/frontend with 6 updates (#1056)
Bumps the npm-deps group in /src/frontend with 6 updates:

| Package | From | To |
| --- | --- | --- |
|
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)
| `7.16.0` | `7.17.0` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.9.1` | `25.9.2` |
|
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
| `19.2.16` | `19.2.17` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) |
`6.15.0` | `6.16.1` |
| [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) |
`0.53.0` | `0.54.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) |
`1.68.0` | `1.69.0` |

Updates `react-router-dom` from 7.16.0 to 7.17.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.17.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.17.0"><code>react-router@7.17.0</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/195a0d03c1417127ccee73853058c8521beb4fce"><code>195a0d0</code></a>
Release v7.17.0 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15145">#15145</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.17.0/packages/react-router-dom">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.9.1 to 25.9.2
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react` from 19.2.16 to 19.2.17
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.15.0 to 6.16.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.16.1</h2>
<ul>
<li>Resolve SvelteKit ./$types in monorepos (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1778">#1778</a>)
(370ef4cefec6540ee7d58249cc402f479ec76405)</li>
</ul>
<h2>Release 6.16.0</h2>
<ul>
<li>Update sponsors data + fix sponsors layout on narrow screen
(fadf13aad5ebc36f7bc2fbc7615bfa77681d3660)</li>
<li>Detect binaries and entry files in node:child_process calls
(fc3598cfac640a2ae53b0113883574bf15bc5d47)</li>
<li>It works™ (2d9ce845121484ef3ff84e4a761cfd98891d6c09)</li>
<li>Extend known issues doc w/ workaround (close <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1763">#1763</a>)
(fcd444bf4c6b2ddc5d7bb0ebfd6f3991cf5d0be2)</li>
<li>Support ignoreExportsUsedInFile per workspace (close <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1495">#1495</a>)
(4b898a971105d865d86d4dc81bc694721bff8793)</li>
<li>feat(vscode): add <code>workspaceRoot</code> config option to enable
use in a VSCode workspace that does not have package.json at the
workspace root (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1667">#1667</a>)
(7c1ebef6ab6d1c5a7f2f920d4243241246b53f4b) - thanks <a
href="https://github.com/anmilleriii"><code>@​anmilleriii</code></a>!</li>
<li>Replace minimist with node:util.parseArgs (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1492">#1492</a>)
(b360c5ce1acfbb2cbd5f4e92ecca6c9b461ae094)</li>
<li>Preserve minimist numeric coercion and --no-x negation
(c12153ce0601378354421e454a6b6bbab74ae9fb)</li>
<li>Simplify parseArgs adapter
(ba15e413be7515620e4224b21483a1a87659dc34)</li>
<li>Detect and credit registered custom elements (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1394">#1394</a>)
(62dcda5fa46ccf6bdd94175b725fd38678049319)</li>
<li>Add Lit and FAST plugins to detect <a
href="https://github.com/customElement"><code>@​customElement</code></a>
classes (348d2c9decf09bb61ab47477bc6cc57e4b089ec3)</li>
<li>Add new testimonials (77fd7ed7dffaccfa8bc024105fe81dbe09b70671)</li>
<li>Scope custom path aliases per workspace (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1775">#1775</a>)
(d908099b52e4fd93b7947bafecbabeddfc7847f3)</li>
<li>Restructure tests (ec4c77941d42aef54bed9e4dd1cae8e8784aa147)</li>
<li>Simplify boolean check in parseArgs adapter
(ba6865de03785eb49b2adf833f7f769eece78d49)</li>
<li>Scope static custom-element define detection to the FAST plugin
(94632cddd15f75eadd204cb480b3df6c1f2a842d)</li>
<li>Add Custom Elements feature docs page
(230bd734652f3a269b70da09cd26ac7e80a210cd)</li>
<li>Update known-issues.md
(f1f4c1bceef9a6575d7b31cc1340538ea894f824)</li>
<li>Fix crash on backtick string literals in plugin config (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1776">#1776</a>)
(f1adc7fbd68fc52a89a4d2a4d6b17d905d051de7)</li>
<li>Format (e4720cab435be48e1a40afa8c548e21bdb74b14e)</li>
<li>Fix backtick string literals in require() and plugin-name config
arrays (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1776">#1776</a>)
(d14eb053331daaaeaec89c3c8e04cfeeba7580af)</li>
<li>Credit custom elements via aliases, scoped registries, and static
blocks (d7cbe12bd904f65b20016bdd2dfd4a5d7c5c1524)</li>
<li>Improve Stencil plugin: credit <a
href="https://github.com/Component"><code>@​Component</code></a> and
recognize test files (152d73052f87f29b348abbab90e117cfb97dd69b)</li>
<li>Add Catalyst plugin to credit bare <a
href="https://github.com/controller"><code>@​controller</code></a>
custom elements (8a37f8c25b03cd4e55bd18ba822906be35fcd97b)</li>
<li>Document Stencil, Catalyst, static-block custom el reg.
(105fba3a829f1cf4cf871035dbc9c170b0de7bc1)</li>
<li>Auto-format md (f4fcf4e1c6a399d761151fc367125416e7741675)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/a3169ec99b4708d7199ed9c38682a7f5f0639b1c"><code>a3169ec</code></a>
Release knip@6.16.1</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/370ef4cefec6540ee7d58249cc402f479ec76405"><code>370ef4c</code></a>
Resolve SvelteKit ./$types in monorepos (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1778">#1778</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/e9a5a64f6d551ceef0bb6667e2c2582b94a77c4f"><code>e9a5a64</code></a>
Release knip@6.16.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/8a37f8c25b03cd4e55bd18ba822906be35fcd97b"><code>8a37f8c</code></a>
Add Catalyst plugin to credit bare <a
href="https://github.com/controller"><code>@​controller</code></a>
custom elements</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/152d73052f87f29b348abbab90e117cfb97dd69b"><code>152d730</code></a>
Improve Stencil plugin: credit <a
href="https://github.com/Component"><code>@​Component</code></a> and
recognize test files</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/d7cbe12bd904f65b20016bdd2dfd4a5d7c5c1524"><code>d7cbe12</code></a>
Credit custom elements via aliases, scoped registries, and static
blocks</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/d14eb053331daaaeaec89c3c8e04cfeeba7580af"><code>d14eb05</code></a>
Fix backtick string literals in require() and plugin-name config arrays
(<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1776">#1776</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/f1adc7fbd68fc52a89a4d2a4d6b17d905d051de7"><code>f1adc7f</code></a>
Fix crash on backtick string literals in plugin config (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1776">#1776</a>)</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/94632cddd15f75eadd204cb480b3df6c1f2a842d"><code>94632cd</code></a>
Scope static custom-element define detection to the FAST plugin</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/ba6865de03785eb49b2adf833f7f769eece78d49"><code>ba6865d</code></a>
Simplify boolean check in parseArgs adapter</li>
<li>Additional commits viewable in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.16.1/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.53.0 to 0.54.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxfmt/CHANGELOG.md">oxfmt's
changelog</a>.</em></p>
<blockquote>
<h2>[0.54.0] - 2026-06-08</h2>
<h3>📚 Documentation</h3>
<ul>
<li>dadafe3 oxlint, oxfmt: Mention migrate skills in npm READMEs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22965">#22965</a>)
(Boshen)</li>
<li>f88961a oxfmt: Annotate each config option with supported languages
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22953">#22953</a>)
(leaysgur)</li>
</ul>
<h2>[0.52.0] - 2026-05-26</h2>
<h3>🚀 Features</h3>
<ul>
<li>16b8058 oxfmt: Support <code>vite-plus/resolveConfig</code> for
vite.config.ts (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22454">#22454</a>)
(leaysgur)</li>
</ul>
<h2>[0.50.0] - 2026-05-15</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>43b9978 formatter/sort_imports: Treat subpath imports as internal
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22440">#22440</a>)
(leaysgur)</li>
</ul>
<h2>[0.49.0] - 2026-05-11</h2>
<h3>🚀 Features</h3>
<ul>
<li>6e8e818 oxfmt: Experimental .svelte support (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/21700">#21700</a>)
(leaysgur)</li>
</ul>
<h2>[0.45.0] - 2026-04-13</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>50c389b oxfmt: Support <code>.editorconfig</code>
<code>quote_type</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/20989">#20989</a>)
(leaysgur)</li>
</ul>
<h2>[0.44.0] - 2026-04-06</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>dd2df87 npm: Export package.json for oxlint and oxfmt (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/20784">#20784</a>)
(kazuya kawaguchi)</li>
<li>4216380 oxfmt: Support <code>.editorconfig</code>
<code>tab_width</code> fallback (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/20988">#20988</a>)
(leaysgur)</li>
</ul>
<h2>[0.43.0] - 2026-03-30</h2>
<h3>🚀 Features</h3>
<ul>
<li>6ef440a oxfmt: Support bool for object style options (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/20853">#20853</a>)
(leaysgur)</li>
</ul>
<h2>[0.42.0] - 2026-03-24</h2>
<h3>🚀 Features</h3>
<ul>
<li>416865a formatter,oxfmt: Add doc comments for
<code>JsdocConfig</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/20644">#20644</a>)
(leaysgur)</li>
<li>4fec907 formatter: Add JSDoc comment formatting support (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/19828">#19828</a>)
(Dunqing)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/44ae845fe19d3700128e50e7e61d98c7a85f3f47"><code>44ae845</code></a>
release(apps): oxlint v1.69.0 &amp;&amp; oxfmt v0.54.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/23116">#23116</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/dadafe3e0874b2b75775d265b24d19d7f446e2bf"><code>dadafe3</code></a>
docs(oxlint, oxfmt): mention migrate skills in npm READMEs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22965">#22965</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/f88961ae2968ae2a12035111d07c72797812d2fd"><code>f88961a</code></a>
docs(oxfmt): annotate each config option with supported languages (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22953">#22953</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.54.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.68.0 to 1.69.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.69.0] - 2026-06-08</h2>
<h3>🚀 Features</h3>
<ul>
<li>e805174 linter: Add schema for <code>jest/vitest/max-expects</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23105">#23105</a>)
(Sysix)</li>
<li>7850577 linter: Add schema for
<code>jest/vitest/expect-expect</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23104">#23104</a>)
(Sysix)</li>
<li>75f641a linter: Add schema for
<code>jest/vitest/consistent-test-it</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23103">#23103</a>)
(Sysix)</li>
<li>5125f89 linter/unicorn: Support no-null <code>checkArguments</code>
option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23098">#23098</a>)
(camc314)</li>
<li>b8b9797 linter: Add schema for <code>import-max-dependencies</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23096">#23096</a>)
(Sysix)</li>
<li>65cb47a linter/eslint: Support no-unused-expressions
<code>ignoreDirectives</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23097">#23097</a>)
(camc314)</li>
<li>f6c36d5 linter: Add schema for
<code>import/prefer-default-export</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23091">#23091</a>)
(Sysix)</li>
<li>0d4a5d1 linter: Add schema for <code>eslint/sort-vars</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23090">#23090</a>)
(Sysix)</li>
<li>fdb5bf5 linter: Add schema for <code>eslint/radix</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23082">#23082</a>)
(Sysix)</li>
<li>05b4dcf linter: Add schema for <code>eslint/prefer-const</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23081">#23081</a>)
(Sysix)</li>
<li>5a06c4d linter/vue: Implement next-tick-style rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23041">#23041</a>)
(Alex Peshkov)</li>
<li>e38a36a linter: Add schema for
<code>eslint/operator-assignment</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23080">#23080</a>)
(Sysix)</li>
<li>907cee7 linter: Add schema for
<code>eslint/no-warning-comments</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23075">#23075</a>)
(Sysix)</li>
<li>9470bb2 linter: Add schema for <code>eslint/no-unused-vars</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23073">#23073</a>)
(Sysix)</li>
<li>234b5cf linter: Add schema for <code>eslint/no-shadow</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23072">#23072</a>)
(Sysix)</li>
<li>de0dd8b linter: Add schema for
<code>eslint/no-restricted-exports</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23020">#23020</a>)
(Sysix)</li>
<li>faa3e0d linter: Add schema for <code>eslint/no-param-reassign</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23018">#23018</a>)
(Sysix)</li>
<li>dbc9c27 linter: Add schema for <code>eslint/no-magic-numbers</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23017">#23017</a>)
(Sysix)</li>
<li>38d3569 linter: Add schema for
<code>eslint/no-inner-declarations</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23016">#23016</a>)
(Sysix)</li>
<li>008fa41 linter: Add schema for
<code>eslint/no-constant-condition</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22991">#22991</a>)
(Sysix)</li>
<li>ca44623 linter: Add schema for <code>eslint/no-empty-function</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22988">#22988</a>)
(Sysix)</li>
<li>43eb04d linter: Add schema for <code>eslint/id-match</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22987">#22987</a>)
(Sysix)</li>
<li>a800f27 linter: Add schema for
<code>eslint/capitalized-comments</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22984">#22984</a>)
(Sysix)</li>
<li>96e2d32 linter: Add schema for <code>eslint/id-length</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22963">#22963</a>)
(Sysix)</li>
<li>545493f linter: Add schema for <code>eslint/complexity</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22960">#22960</a>)
(Sysix)</li>
<li>5f0b558 linter: Add schema for
<code>eslint/class-methods-use-this</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22959">#22959</a>)
(Sysix)</li>
<li>719b720 linter: Add schema for simple rule configurations (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22948">#22948</a>)
(Sysix)</li>
<li>fd00966 linter: Add right schema for <code>eslint/max-*</code> rules
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22923">#22923</a>)
(Sysix)</li>
<li>1226d78 linter: Fill schema with rule configurations (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22907">#22907</a>)
(Sysix)</li>
<li>8f423c1 linter/vue: Implement <code>require-direct-export</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/17623">#17623</a>)
(yefan)</li>
<li>78e915b linter/vue: Implement no-reserved-props rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22914">#22914</a>)
(bab)</li>
<li>0f200a9 linter/vue: Implement require-prop-types rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22083">#22083</a>)
(Alex Peshkov)</li>
<li>5da9da9 linter/vue: Implement no-reserved-keys rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/21780">#21780</a>)
(bab)</li>
<li>75e14a8 linter/vue: Implement prop-name-casing rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22892">#22892</a>)
(bab)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>0383e61 linter: Fix schema for rules without a config (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22946">#22946</a>)
(Sysix)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>dadafe3 oxlint, oxfmt: Mention migrate skills in npm READMEs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22965">#22965</a>)
(Boshen)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/44ae845fe19d3700128e50e7e61d98c7a85f3f47"><code>44ae845</code></a>
release(apps): oxlint v1.69.0 &amp;&amp; oxfmt v0.54.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23116">#23116</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/e8051744a1bd8cd97e91f1c397f58ca9e81d4edb"><code>e805174</code></a>
feat(linter): add schema for <code>jest/vitest/max-expects</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23105">#23105</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/78505778061a70d0469382a8e786a2696a24fe74"><code>7850577</code></a>
feat(linter): add schema for <code>jest/vitest/expect-expect</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23104">#23104</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/75f641aa7388b18c14393b7b745c9cb03ec31c0b"><code>75f641a</code></a>
feat(linter): add schema for <code>jest/vitest/consistent-test-it</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23103">#23103</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/d65b860b357e12120ea1f08794e1e7cfb4b5e6b7"><code>d65b860</code></a>
refactor(linter): reuse non-object references for rules schemas (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23100">#23100</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/6bcd52ccdeb5c8a1ccb5fc3b1eb9227c08b7d932"><code>6bcd52c</code></a>
refactor(linter): share <code>&quot;alway&quot; |
&quot;never&quot;</code> option across rules (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23099">#23099</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/5125f8955ab27e4a9673f1cf34bc9d8f0aa6c6a7"><code>5125f89</code></a>
feat(linter/unicorn): support no-null <code>checkArguments</code> option
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23098">#23098</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/b8b97973c4fb7b6134a103a1c57c50db4b3d0bef"><code>b8b9797</code></a>
feat(linter): add schema for <code>import-max-dependencies</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23096">#23096</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/65cb47a197a07d3a570341ff3c3f69bb77cfd8ed"><code>65cb47a</code></a>
feat(linter/eslint): support no-unused-expressions
<code>ignoreDirectives</code> option ...</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/f6c36d54d92a372b5b9486892227d34f43160cfa"><code>f6c36d5</code></a>
feat(linter): add schema for <code>import/prefer-default-export</code>
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/23091">#23091</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.69.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-14 00:10:02 -04:00
dependabot[bot] bce5ea0641 Bump the gh-actions group with 2 updates (#1057)
Bumps the gh-actions group with 2 updates:
[astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and
[github/codeql-action](https://github.com/github/codeql-action).

Updates `astral-sh/setup-uv` from 8.1.0 to 8.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/setup-uv/releases">astral-sh/setup-uv's
releases</a>.</em></p>
<blockquote>
<h2>v8.2.0 🌈 New inputs <code>quiet</code> and
<code>download-from-astral-mirror</code></h2>
<h2>Changes</h2>
<p>This release brings two new inputs and a few bug fixes.</p>
<h3>New inputs</h3>
<p>Lets talk about the new inputs first.</p>
<h4>quiet</h4>
<p>Pretty simple. It turns of all <code>info</code> loggings. Useful if
you use this in a composite action and are not interested in all the
details.
In the upcoming releases we will add log groups to fully implement
support for &quot;less noise&quot;</p>
<blockquote>
<p>[!NOTE]<br />
Warnings and errors are always logged.</p>
</blockquote>
<h4>download-from-astral-mirror</h4>
<p>In some cases you may want to directly use the fallback of checking
for available versions and downloading releases from GitHub instead of
using the astral.sh mirror. Setting <code>download-from-astral-mirror:
false</code> allows you to do that.</p>
<h3>Bugfixes</h3>
<p>When using the astral.sh mirror to query available versions and
download releases (done by default) we now stop sending the GitHub token
in the header. The mirror never looked at it but we shouldn't be handing
out that data even if it is just a short lived token.
All other bugfixes try to limit the impact of failed GitHub queries due
to retries and other faults.</p>
<p>We couldn't pinpoint all rootcauses yet but added more logging for
error cases to track them down.</p>
<h2>🐛 Bug fixes</h2>
<ul>
<li>fix: report unexpected cache save failures <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/896">#896</a>)</li>
<li>fix: report unexpected setup failures <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/895">#895</a>)</li>
<li>fix: add timeout to fetch to prevent silent hangs <a
href="https://github.com/eifinger-bot"><code>@​eifinger-bot</code></a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/883">#883</a>)</li>
<li>Limit GitHub tokens to github.com download URLs <a
href="https://github.com/zsol"><code>@​zsol</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/878">#878</a>)</li>
<li>increase libuv-workaround timeout to 100ms <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/880">#880</a>)</li>
</ul>
<h2>🚀 Enhancements</h2>
<ul>
<li>Add quiet input to suppress info-level log output <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/898">#898</a>)</li>
<li>feat: add <code>download-from-astral-mirror</code> input <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/897">#897</a>)</li>
</ul>
<h2>🧰 Maintenance</h2>
<ul>
<li>docs: update dependabot rollup biome guidance <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/902">#902</a>)</li>
<li>chore: update known checksums for 0.11.18 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/899">#899</a>)</li>
<li>chore: update known checksums for 0.11.17 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/892">#892</a>)</li>
<li>chore: update known checksums for 0.11.16 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/889">#889</a>)</li>
<li>chore: update known checksums for 0.11.15 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/885">#885</a>)</li>
<li>chore: update known checksums for 0.11.14 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/879">#879</a>)</li>
<li>chore: update known checksums for 0.11.13 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/877">#877</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/fac544c07dec837d0ccb6301d7b5580bf5edae39"><code>fac544c</code></a>
chore(deps): roll up dependabot updates (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/903">#903</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/7390f777b051d6c47c9cb905ff80e7d5d85a7068"><code>7390f77</code></a>
docs: update dependabot rollup biome guidance (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/902">#902</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/363c64a728451954156ddb9e3f368b879eeee5da"><code>363c64a</code></a>
chore(deps): roll up dependabot updates (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/901">#901</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/c4fcbafce4f941a09e04c45c42db7a2e3ba5cd91"><code>c4fcbaf</code></a>
chore(deps): bump release-drafter/release-drafter from 7.3.0 to 7.3.1
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/900">#900</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/8e642c5e623b521f8b6b15bbc2ba54bae583fe45"><code>8e642c5</code></a>
chore: update known checksums for 0.11.18 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/899">#899</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/a92cb430984b4b2b34c9c47e020cf035089958fa"><code>a92cb43</code></a>
Add quiet input to suppress info-level log output (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/898">#898</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/e07f2ac4b796a5fa8dc51ebf0a5187d0463eb4d6"><code>e07f2ac</code></a>
chore(deps): bump eifinger/actionlint-action from 1.10.1 to 1.10.2 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/842">#842</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/bc4034eedf3a6f77238660a28089c6b201eae39f"><code>bc4034e</code></a>
chore(deps): bump github/codeql-action from 4.35.4 to 4.36.0 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/893">#893</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/df42d4f6ba41cdcf6eda832c32439db37cc28b39"><code>df42d4f</code></a>
chore(deps): bump zizmorcore/zizmor-action from 0.5.5 to 0.5.6 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/891">#891</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/b9c8c4c7baf912cbda30843477d08b3f63b0f660"><code>b9c8c4c</code></a>
feat: add <code>download-from-astral-mirror</code> input (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/897">#897</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/setup-uv/compare/08807647e7069bb48b6ef5acd8ec9567f424441b...fac544c07dec837d0ccb6301d7b5580bf5edae39">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 4.36.1 to 4.36.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.36.2</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.36.2 - 04 Jun 2026</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
<h2>4.36.1 - 02 Jun 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.0 - 22 May 2026</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>4.35.5 - 15 May 2026</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
<h2>4.35.4 - 07 May 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li>
</ul>
<h2>4.35.3 - 01 May 2026</h2>
<ul>
<li><em>Upcoming breaking change</em>: Add a deprecation warning for
customers using CodeQL version 2.19.3 and earlier. These versions of
CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise
Server 3.15, and will be unsupported by the next minor release of the
CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3837">#3837</a></li>
<li>Configurations for private registries that use Cloudsmith or GCP
OIDC are now accepted. <a
href="https://redirect.github.com/github/codeql-action/pull/3850">#3850</a></li>
<li>Best-effort connection tests for private registries now use
<code>GET</code> requests instead of <code>HEAD</code> for better
compatibility with various registry implementations. For NuGet feeds,
the test is now always performed against the service index. <a
href="https://redirect.github.com/github/codeql-action/pull/3853">#3853</a></li>
<li>Fixed a bug where two diagnostics produced within the same
millisecond could overwrite each other on disk, causing one of them to
be lost. <a
href="https://redirect.github.com/github/codeql-action/pull/3852">#3852</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3">2.25.3</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3865">#3865</a></li>
</ul>
<h2>4.35.2 - 15 Apr 2026</h2>
<ul>
<li>The undocumented TRAP cache cleanup feature that could be enabled
using the <code>CODEQL_ACTION_CLEANUP_TRAP_CACHES</code> environment
variable is deprecated and will be removed in May 2026. If you are
affected by this, we recommend disabling TRAP caching by passing the
<code>trap-caching: false</code> input to the <code>init</code> Action.
<a
href="https://redirect.github.com/github/codeql-action/pull/3795">#3795</a></li>
<li>The Git version 2.36.0 requirement for improved incremental analysis
now only applies to repositories that contain submodules. <a
href="https://redirect.github.com/github/codeql-action/pull/3789">#3789</a></li>
<li>Python analysis on GHES no longer extracts the standard library,
relying instead on models of the standard library. This should result in
significantly faster extraction and analysis times, while the effect on
alerts should be minimal. <a
href="https://redirect.github.com/github/codeql-action/pull/3794">#3794</a></li>
<li>Fixed a bug in the validation of OIDC configurations for private
registries that was added in CodeQL Action 4.33.0 / 3.33.0. <a
href="https://redirect.github.com/github/codeql-action/pull/3807">#3807</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.2">2.25.2</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3823">#3823</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/8aad20d150bbac5944a9f9d289da16a4b0d87c1e"><code>8aad20d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3949">#3949</a>
from github/update-v4.36.2-dcb947ce1</li>
<li><a
href="https://github.com/github/codeql-action/commit/f521b08cd8f468ab193ea950a589cb2e9c869c6a"><code>f521b08</code></a>
Add additional changelog notes</li>
<li><a
href="https://github.com/github/codeql-action/commit/8aeff0ffb7b78582ee0d0e6eebb8140684400d08"><code>8aeff0f</code></a>
Update changelog for v4.36.2</li>
<li><a
href="https://github.com/github/codeql-action/commit/dcb947ce15976d40ea82935510b2db4872ec124c"><code>dcb947c</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3948">#3948</a>
from github/update-bundle/codeql-bundle-v2.25.6</li>
<li><a
href="https://github.com/github/codeql-action/commit/c251bcefa178f7780f62f150002acffe3d07fde9"><code>c251bce</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/62953c18b35f59e28351d2f1e806925aef8b1e3c"><code>62953c1</code></a>
Update default bundle to codeql-bundle-v2.25.6</li>
<li><a
href="https://github.com/github/codeql-action/commit/423b570baf1976cd7a3daeba5d6e9f9b76432f37"><code>423b570</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3946">#3946</a>
from github/dependabot/npm_and_yarn/npm-minor-5d507a...</li>
<li><a
href="https://github.com/github/codeql-action/commit/c35d1b164463ee62a100735382aaaa525c5d3496"><code>c35d1b1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3947">#3947</a>
from github/dependabot/github_actions/dot-github/wor...</li>
<li><a
href="https://github.com/github/codeql-action/commit/cb1a588b02755b176e7b9d033ed4b69312f0e1bd"><code>cb1a588</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3937">#3937</a>
from github/robertbrignull/waitForProcessing_backoff</li>
<li><a
href="https://github.com/github/codeql-action/commit/ba47406412c54532b5b4fcfbaf877c9e2382b206"><code>ba47406</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3943">#3943</a>
from github/henrymercer/cache-cli-version-info</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/87557b9c84dde89fdd9b10e88954ac2f4248e463...8aad20d150bbac5944a9f9d289da16a4b0d87c1e">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-14 00:09:58 -04:00
spindrift 0633cfde87 Add content_type=combined URL parameter and FORCE_COMBINED_SEARCH user setting (#1058)
Adds support for `content_type=combined` in URL search parameters,
letting users force combined-mode searches via a bookmarkable link
rather than relying on the last-used preference from localStorage.

The override is applied only in Universal mode and only when combined
mode is actually available (universal enabled, `show_combined_selector`
on, neither content type blocked by policy). Otherwise, it's silently
ignored, consistent with how `content_type=ebook`/`audiobook` already
behave outside Universal.

Existing `content_type=ebook`/`audiobook` URLs now also force combined
mode off, so the URL is authoritative regardless of prior preference.

Also adds a per-user `FORCE_COMBINED_SEARCH` setting that locks combined
mode on whenever it's available.

URL `content_type=ebook`/`audiobook` overrides are also superseded by
force-combined for the same reason: the search bar wouldn't let users
switch back, so honoring the URL param would leave them in a state they
couldn't escape from.
2026-06-14 00:09:30 -04:00
dependabot[bot] b2131fa940 Bump the python-deps group across 1 directory with 2 updates (#1054)
Bumps the python-deps group with 2 updates in the / directory:
[flask-cors](https://github.com/corydolphin/flask-cors) and
[basedpyright](https://github.com/detachhead/basedpyright).

Updates `flask-cors` from 6.0.3 to 6.0.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/corydolphin/flask-cors/releases">flask-cors's
releases</a>.</em></p>
<blockquote>
<h2>6.0.5</h2>
<p>Supersedes 6.0.4</p>
<h2>What's Changed</h2>
<ul>
<li>Add MyPy Typing and modernize options parsing by <a
href="https://github.com/corydolphin"><code>@​corydolphin</code></a> in
<a
href="https://redirect.github.com/corydolphin/flask-cors/pull/409">corydolphin/flask-cors#409</a>
(this broke strict type checking when using Blueprints)</li>
<li>Restore Blueprint support in CORS type signatures (<a
href="https://redirect.github.com/corydolphin/flask-cors/issues/410">#410</a>)
by <a
href="https://github.com/corydolphin"><code>@​corydolphin</code></a> in
<a
href="https://redirect.github.com/corydolphin/flask-cors/pull/411">corydolphin/flask-cors#411</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.3...6.0.5">https://github.com/corydolphin/flask-cors/compare/6.0.3...6.0.5</a></p>
<h2>6.0.4</h2>
<h2>What's Changed</h2>
<ul>
<li>Add MyPy Typing by <a
href="https://github.com/corydolphin"><code>@​corydolphin</code></a> in
<a
href="https://redirect.github.com/corydolphin/flask-cors/pull/409">corydolphin/flask-cors#409</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.3...6.0.4">https://github.com/corydolphin/flask-cors/compare/6.0.3...6.0.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/corydolphin/flask-cors/commit/91ebc49c25aaf76b0e53e925feef1e3f19617c87"><code>91ebc49</code></a>
Typing Hotfix: support blueprints in the type system</li>
<li><a
href="https://github.com/corydolphin/flask-cors/commit/d601665840bdf128912573c9b02e1b55062625a1"><code>d601665</code></a>
Add strict MyPy Typing</li>
<li>See full diff in <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.3...6.0.5">compare
view</a></li>
</ul>
</details>
<br />

Updates `basedpyright` from 1.39.6 to 1.39.7
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/c9a757d246d3301e992796278216a2120b8163b0"><code>c9a757d</code></a>
1.39.7</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/d253d82094093686e95fa4b0d12ced13f8094d79"><code>d253d82</code></a>
avoid duplicated capability registrations</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/19c354517cc1e1341b9a90d7f672a1edfa4b1b97"><code>19c3545</code></a>
fix empty semantic tokens response interfering with other language
servers wh...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/b0181925c9bb68eebd394764ceb54531c6b23c56"><code>b018192</code></a>
update baseline file</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/15ee8f1eacd803fdbfa4915d4e402c6bd962df97"><code>15ee8f1</code></a>
revert upstream's ai generated bash clusterfuck of an attempt at fixing
the p...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/daec470463d8fe39e1c83d1abfa17748b3cdfe60"><code>daec470</code></a>
try using pyprojectx to install primer instead of uv</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/f9650c5b2e87a3a8a81bda43010ec25a555116e1"><code>f9650c5</code></a>
update mypy_primer repo</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/48fe1c8fc731b2a9812a2b742a608ee1ce1c8286"><code>48fe1c8</code></a>
don't recurse submodules when cloning repos in the primer, it screws up
becau...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/af9a1fd8fd67f8d2ac697965b617a85aa70b8a20"><code>af9a1fd</code></a>
fix completely useless <code>CalledProcesError</code> messages</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/3b5becb063a7a8b76727317bc4abef2fd44294e8"><code>3b5becb</code></a>
update this project's basedpyright/ruff config for the mypy_primer
repo</li>
<li>Additional commits viewable in <a
href="https://github.com/detachhead/basedpyright/compare/v1.39.6...v1.39.7">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-12 00:23:48 -04:00
dependabot[bot]andCaliBrain 7e8a0248a0 Bump the python-deps group with 2 updates (#1051)
Bumps the python-deps group with 2 updates:
[flask-cors](https://github.com/corydolphin/flask-cors) and
[qbittorrent-api](https://github.com/rmartin16/qbittorrent-api).

Updates `flask-cors` from 6.0.2 to 6.0.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/corydolphin/flask-cors/releases">flask-cors's
releases</a>.</em></p>
<blockquote>
<h2>6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Derive package version from git tag via setuptools-scm by <a
href="https://github.com/corydolphin"><code>@​corydolphin</code></a> in
<a
href="https://redirect.github.com/corydolphin/flask-cors/pull/405">corydolphin/flask-cors#405</a></li>
<li>Improve CI/CD security with least privilege and build separation by
<a href="https://github.com/corydolphin"><code>@​corydolphin</code></a>
in <a
href="https://redirect.github.com/corydolphin/flask-cors/pull/406">corydolphin/flask-cors#406</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.3">https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.3</a></p>
<h2>6.0.3-pre</h2>
<h2>What's Changed</h2>
<ul>
<li>Derive package version from git tag via setuptools-scm by <a
href="https://github.com/corydolphin"><code>@​corydolphin</code></a> in
<a
href="https://redirect.github.com/corydolphin/flask-cors/pull/405">corydolphin/flask-cors#405</a></li>
<li>Improve CI/CD security with least privilege and build separation by
<a href="https://github.com/corydolphin"><code>@​corydolphin</code></a>
in <a
href="https://redirect.github.com/corydolphin/flask-cors/pull/406">corydolphin/flask-cors#406</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.3">https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/corydolphin/flask-cors/commit/c8e8871076c7ed378eb0ae773a2079b6d62ed7a9"><code>c8e8871</code></a>
Harden release publishing workflow (<a
href="https://redirect.github.com/corydolphin/flask-cors/issues/406">#406</a>)</li>
<li><a
href="https://github.com/corydolphin/flask-cors/commit/e1d4034e2b2d5232f6fed27bc753f90331747b64"><code>e1d4034</code></a>
Derive package version from git tag via setuptools-scm (<a
href="https://redirect.github.com/corydolphin/flask-cors/issues/405">#405</a>)</li>
<li>See full diff in <a
href="https://github.com/corydolphin/flask-cors/compare/6.0.2...6.0.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `qbittorrent-api` from 2026.5.1 to 2026.6.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/releases">qbittorrent-api's
releases</a>.</em></p>
<blockquote>
<h2>release-2026.6.0</h2>
<h2>What's Changed</h2>
<h3>Features</h3>
<ul>
<li>Add processInfo to API by <a
href="https://github.com/GordonFreemanK"><code>@​GordonFreemanK</code></a>
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/626">rmartin16/qbittorrent-api#626</a></li>
</ul>
<h3>Fixes</h3>
<ul>
<li>fix: correct syntax errors in code examples in
behavior&amp;configuration.rst by <a
href="https://github.com/AmSach"><code>@​AmSach</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/627">rmartin16/qbittorrent-api#627</a></li>
</ul>
<h3>Chores</h3>
<ul>
<li>Bump pre-commit hook for ruff-pre-commit from v0.15.12 to v0.15.15
by <a href="https://github.com/rmartin16"><code>@​rmartin16</code></a>
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/622">rmartin16/qbittorrent-api#622</a></li>
<li>Bump pre-commit hook for mirrors-mypy from v1.20.2 to v2.1.0 by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/621">rmartin16/qbittorrent-api#621</a></li>
<li>Bump the github-actions group with 3 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/623">rmartin16/qbittorrent-api#623</a></li>
<li>use uv for project orchestration by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/624">rmartin16/qbittorrent-api#624</a></li>
<li>Bump actions/cache from 4 to 5 in the github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/625">rmartin16/qbittorrent-api#625</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/AmSach"><code>@​AmSach</code></a> made
their first contribution in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/627">rmartin16/qbittorrent-api#627</a></li>
<li><a
href="https://github.com/GordonFreemanK"><code>@​GordonFreemanK</code></a>
made their first contribution in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/626">rmartin16/qbittorrent-api#626</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.3...v2026.6.0">https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.3...v2026.6.0</a></p>
<h2>release-2026.5.3</h2>
<h2>What's Changed</h2>
<ul>
<li>minimum python 3.10 by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/618">rmartin16/qbittorrent-api#618</a></li>
<li>add support for auth via api key by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/620">rmartin16/qbittorrent-api#620</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.2...v2026.5.3">https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.2...v2026.5.3</a></p>
<h2>release-2026.5.2</h2>
<h2>What's Changed</h2>
<ul>
<li>add support for share limits mode by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/614">rmartin16/qbittorrent-api#614</a></li>
<li>document &quot;Default&quot; option for share_limit_action parameter
by <a
href="https://github.com/HertogArjan"><code>@​HertogArjan</code></a> in
<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/616">rmartin16/qbittorrent-api#616</a></li>
<li>advertise support for qBittorrent v5.2.1 by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/617">rmartin16/qbittorrent-api#617</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.1...v2026.5.2">https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.1...v2026.5.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md">qbittorrent-api's
changelog</a>.</em></p>
<blockquote>
<h3>v2026.6.0 (5 jun 2026)</h3>
<ul>
<li>Add support for <code>app/processInfo</code></li>
</ul>
<h3>v2026.5.3 (30 may 2026)</h3>
<ul>
<li>Add support for API key authentication (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/620">#620</a>)</li>
<li>Minimum Python is now 3.10 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/618">#618</a>)</li>
</ul>
<h3>v2026.5.2 (30 may 2026)</h3>
<ul>
<li>Advertise support for qBittorrent v5.2.1</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/0bd26a9f44c113a315146428c3fd78408bc2c985"><code>0bd26a9</code></a>
Add processInfo to API (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/626">#626</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/c68695ca517a13956e8377c782afeb4c06b71e73"><code>c68695c</code></a>
fix: correct syntax errors in code examples in
behavior&amp;configuration.rst (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/627">#627</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/80f0557f7a39938572a7b77a80a06ade981a6d8a"><code>80f0557</code></a>
Bump actions/cache from 4 to 5 in the github-actions group (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/625">#625</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/9c828e7bc38b17aaddd798edb4cf65657bec5c9d"><code>9c828e7</code></a>
use uv for project orchestration (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/624">#624</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/95c1daec209d54f723bc48e21254a9cffa3072dd"><code>95c1dae</code></a>
Bump the github-actions group with 3 updates (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/623">#623</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/e56e6131a3d3eddee759b61e50d633cd96aa0736"><code>e56e613</code></a>
Bumped pre-commit hook for mirrors-mypy from v1.20.2 to v2.1.0 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/621">#621</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/e2dbe0f8c30bdea9f8fb497ca9c89ceb67099e4a"><code>e2dbe0f</code></a>
Bumped pre-commit hook for ruff-pre-commit from v0.15.12 to v0.15.15 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/622">#622</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/1e3716a71796ed0769756d6f6dabf1de9204b614"><code>1e3716a</code></a>
bump to v2026.5.3</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/0e8476f6d1a2023d4d4e7a32e875a79aa815bb61"><code>0e8476f</code></a>
add support for auth via api key (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/620">#620</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/f606b854959776204836a76b1e5a9aef959acc67"><code>f606b85</code></a>
Bump the pip group with 8 updates (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/619">#619</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.1...v2026.6.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-10 03:26:50 -04:00
CaliBrain b914f77748 Fix CI/CD issues (#1052) 2026-06-10 03:17:40 -04:00
5f3a94d3b2 fix(transmission): handle completion when seed ratio is 0 (#1023)
## Description
When using Transmission as the torrent client with a seed ratio/limit
set to `0` (so it immediately stops seeding upon completion), the
torrent moves directly to the `"stopped"` state upon reaching 100%
completion.
Previously, `transmission.py` strictly checked that the state was
`"seeding"` to mark it complete:
  ```python
complete = progress >= _SEEDING_PROGRESS_PERCENT and status_value ==
"seeding"
  ```
Because of this, the completed torrent was never marked as finished, and
Shelfmark got stuck in an infinite polling loop. After 5 minutes, the
orchestrator's stall detector triggered and cancelled the download in
the queue (even though the files were fully downloaded and sitting in
  the complete directory).
  ## Fix
Updated the completion check in
`shelfmark/download/clients/transmission.py` to allow `"stopped"` as a
completed state as long as progress is 100%. This aligns it with how
other torrent clients (like qBittorrent and Deluge) handle completion:
  ```python
complete = progress >= _SEEDING_PROGRESS_PERCENT and status_value in
("seeding", "stopped")
  ```
  ## Related Issue
  Fixes #1022

Co-authored-by: cfoucher <cfoucher@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 20:55:38 -04:00
dependabot[bot]andCaliBrain 5d5b8d4bef Bump the python-deps group across 1 directory with 8 updates (#1049)
Bumps the python-deps group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [python-socketio](https://github.com/miguelgrinberg/python-socketio) |
`5.16.1` | `5.16.2` |
| [tqdm](https://github.com/tqdm/tqdm) | `4.67.3` | `4.68.1` |
| [gevent](https://github.com/gevent/gevent) | `26.4.0` | `26.5.0` |
| [apprise](https://github.com/caronc/apprise) | `1.10.0` | `1.11.0` |
| [seleniumbase](https://github.com/seleniumbase/SeleniumBase) |
`4.48.4` | `4.49.7` |
| [basedpyright](https://github.com/detachhead/basedpyright) | `1.39.3`
| `1.39.6` |
| [prek](https://github.com/j178/prek) | `0.3.13` | `0.4.4` |
| [ruff](https://github.com/astral-sh/ruff) | `0.15.12` | `0.15.16` |


Updates `python-socketio` from 5.16.1 to 5.16.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/miguelgrinberg/python-socketio/releases">python-socketio's
releases</a>.</em></p>
<blockquote>
<h2>Release 5.16.2</h2>
<p>See <a
href="https://github.com/miguelgrinberg/python-socketio/blob/main/CHANGES.md">CHANGES.md</a>
for release notes.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/miguelgrinberg/python-socketio/blob/main/CHANGES.md">python-socketio's
changelog</a>.</em></p>
<blockquote>
<h1>python-socketio change log</h1>
<p><strong>Release 5.16.2</strong> - 2026-05-21</p>
<ul>
<li>Prevent unnecessary resource allocations <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1574">#1574</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/ca140fe44d0ceb3004073645222abec182d8784b">commit</a>)</li>
<li>Add zizmor to CI builds <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1570">#1570</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/664dc27ec6f34179ed1724430eda3520627fc642">commit</a>)</li>
</ul>
<p><strong>Release 5.16.1</strong> - 2026-02-06</p>
<ul>
<li>Use configured JSON module in managers <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1549">#1549</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/6229261ae6e8c01e675097242e333ee84587a544">commit</a>)</li>
<li>Admin UI fixes: remove duplicate tasks, report transport upgrades
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1c2eab13a92fac9e43663eb0b5f099eb1c40ea5b">commit</a>)</li>
<li>Switch to Furo documentation template (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/add47d8c7abca697a2804141bbf29bfb095f7d5e">commit</a>)</li>
<li>Add Python free-threading to CI <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1554">#1554</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/ccdd2004a038ae4b8171a05120c5d0787332f7ee">commit</a>)</li>
</ul>
<p><strong>Release 5.16.0</strong> - 2025-12-24</p>
<ul>
<li>Address deprecation warnings (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/b235699d9b06564753c570b76055997e9d62a938">commit</a>)</li>
<li>Drop Python 3.8 and 3.9 from CI builds (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/d0728d2f74538762dd551fa9cd0cd1fd5aedfa37">commit</a>)</li>
</ul>
<p><strong>Release 5.15.1</strong> - 2025-12-16</p>
<ul>
<li>Restore support multiple arguments via pubsub emits <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1540">#1540</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/c279f26bb8c9887c4ca99d4d81ad331c4844438c">commit</a>)</li>
</ul>
<p><strong>Release 5.15.0</strong> - 2025-11-22</p>
<ul>
<li>Retry initial Redis connection <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1536">#1534</a>
([commit <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1">#1</a>](<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1e903e173a2d7b04599c4f7f9630c1abbb531fad">https://github.com/miguelgrinberg/python-socketio/commit/1e903e173a2d7b04599c4f7f9630c1abbb531fad</a>)
[commit <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/2">#2</a>](<a
href="https://github.com/miguelgrinberg/python-socketio/commit/5e898a9b93526e6e667767e54c60f4c84589989d">https://github.com/miguelgrinberg/python-socketio/commit/5e898a9b93526e6e667767e54c60f4c84589989d</a>))</li>
<li>Correctly regenerate RabbitMQ binding after a connection failure <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1516">#1516</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/c52e93b4a328d98a968bfbdec0cfd598b73ee913">commit</a>)
(thanks <strong>Gritty_dev</strong>!)</li>
<li>Support <code>ext_type</code> in the <code>MsgPackPacket</code>
class <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1521">#1521</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/208925344a48485d2cd56e40eb74266c3bcb5311">commit</a>)</li>
<li>Support sending <code>bytesarray</code>s when using pub/sub managers
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/6c9b9974f72e2efdf62407ecab24ee6995448098">commit</a>)</li>
<li>Fix typos in documentation <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1520">#1520</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/db3f1c2a0105c30cb833ddfca8f05fe4320468fd">commit</a>)
(thanks <strong>Lê Nam Khánh</strong>!)</li>
<li>Improvements to the logging documentation (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/b423d0e38eef559b7e81acb7e32059de305f982c">commit</a>)</li>
</ul>
<p><strong>Release 5.14.3</strong> - 2025-10-29</p>
<ul>
<li>Support Python's native <code>ConnectionRefusedError</code>
exception to reject a connection <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1515">#1515</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/f3b18bde3f16437b223491d4c3e440ea37105fe3">commit</a>)</li>
<li>Push binary data to the aiopika client manager <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1514">#1514</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/194e1b7f277b5f72e1de78d3f614e7b8b6c788ac">commit</a>)</li>
</ul>
<p><strong>Release 5.14.2</strong> - 2025-10-15</p>
<ul>
<li>Restore binary message support in message queue setups <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1509">#1509</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/bab4a10f48aaae11d7f832ebe5c30ad3f85d31b3">commit</a>)</li>
<li>Fix formatting of client connection error <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1507">#1507</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/f298c9b54d76ab09ff72935937e1b9575bc45ffd">commit</a>)</li>
<li>Add 3.14 and pypy-3.11 CI tasks (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/1f4cd3b025c294f25208ec3c05b5f8df6209e403">commit</a>)</li>
<li>Improve documentation of the
<code>BaseManager.get_participants()</code> method (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/33722a0d96036f005188b07b8b46a5ef091fe65f">commit</a>)</li>
</ul>
<p><strong>Release 5.14.1</strong> - 2025-10-02</p>
<ul>
<li>Restore support for <code>rediss://</code> URLs, and add support for
<code>valkeys://</code> as well (<a
href="https://github.com/miguelgrinberg/python-socketio/commit/6e2d0de12bb4e4a99fdfc30bed0706ded620822c">commit</a>)</li>
<li>Add support for Redis connections using unix sockets <a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1503">#1503</a>
(<a
href="https://github.com/miguelgrinberg/python-socketio/commit/a8deb3a8f3ee51d75c124157efa7fc9289fd592b">commit</a>)
(thanks <strong>Darren Chang</strong>!)</li>
</ul>
<p><strong>Release 5.14.0</strong> - 2025-09-30</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/6e2b7175c97c2785edd2ea60df026c12240c785c"><code>6e2b717</code></a>
Release 5.16.2</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/cb658291085842372a16863d83e14373f85b3d3e"><code>cb65829</code></a>
update python-engineio version</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/ca140fe44d0ceb3004073645222abec182d8784b"><code>ca140fe</code></a>
prevent unnecessary resource allocation (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1574">#1574</a>)</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/b29beef6bfd38d5a3c3b89da96b7a4574a91efcf"><code>b29beef</code></a>
tox configuration</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/e8981302a3d5b525ee73c2ec9c13859ce2f764e8"><code>e898130</code></a>
Bump ujson from 5.4.0 to 5.12.1 in /examples/server/sanic (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1573">#1573</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/05c32f5da85fe5e5d647c937c7eab0972760ca05"><code>05c32f5</code></a>
Bump qs and body-parser in /examples/server/javascript (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1572">#1572</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/287dc6715b801d319f5baa0fb727e232e728b8aa"><code>287dc67</code></a>
Bump qs and body-parser in /examples/client/javascript (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1571">#1571</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/664dc27ec6f34179ed1724430eda3520627fc642"><code>664dc27</code></a>
add zizmor to ci (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1570">#1570</a>)</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/14c62366a85cfe34e0bd69a22b905eb329873dd3"><code>14c6236</code></a>
Bump django in /examples/server/wsgi/django_socketio (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1566">#1566</a>)
#nolog</li>
<li><a
href="https://github.com/miguelgrinberg/python-socketio/commit/29b2e5cdbe87e8216bc46fccb864b84ab9f55cf9"><code>29b2e5c</code></a>
Bump aiohttp from 3.13.3 to 3.13.4 in /examples/server/aiohttp (<a
href="https://redirect.github.com/miguelgrinberg/python-socketio/issues/1565">#1565</a>)
#nolog</li>
<li>Additional commits viewable in <a
href="https://github.com/miguelgrinberg/python-socketio/compare/v5.16.1...v5.16.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `tqdm` from 4.67.3 to 4.68.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tqdm/tqdm/releases">tqdm's
releases</a>.</em></p>
<blockquote>
<h2>tqdm v4.68.1 stable</h2>
<ul>
<li>set name of monitor thread (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1669">#1669</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/1752">#1752</a> &lt;-
<a
href="https://redirect.github.com/tqdm/tqdm/issues/1435">#1435</a>)</li>
<li>fix monitor thread <code>atexit</code> deadlock (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1751">#1751</a> &lt;-
<a href="https://redirect.github.com/tqdm/tqdm/issues/528">#528</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/627">#627</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/1435">#1435</a>, <a
href="https://redirect.github.com/tqdm/tqdm/issues/1564">#1564</a>)</li>
<li>docs: minor copyediting</li>
</ul>
<h2>tqdm v4.68.0 stable</h2>
<ul>
<li><code>utils</code>: simplify terminal size detection (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a>)</li>
<li><code>contrib</code>
<ul>
<li><code>itertools</code> (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a>)
<ul>
<li>add <code>chain</code>, <code>permutations</code>,
<code>combinations</code>, <code>combinations_with_replacement</code>,
<code>batched</code></li>
<li>add <code>product(repeat=1)</code> keyword argument (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1428">#1428</a>)</li>
</ul>
</li>
<li>fix <code>discord</code>, <code>telegram</code> error handling</li>
<li>fix <code>discord</code>, <code>slack</code>, <code>telegram</code>
format for <code>total=None</code></li>
</ul>
</li>
<li>soft-deprecate <code>tqdm.utils.envwrap</code> -&gt; <a
href="https://github.com/tqdm/envwrap"><code>envwrap</code></a></li>
<li>benchmarks: fix <code>asv</code></li>
<li>misc linting</li>
<li>misc framework updates
<ul>
<li>CI: migrate manual job to <code>pre-commit.ci</code></li>
<li>bump workflow actions &amp; pre-commit hooks</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tqdm/tqdm/commit/67cf355f96dfc3e459d18193d68a98a7abb6e08e"><code>67cf355</code></a>
Merge pull request <a
href="https://redirect.github.com/tqdm/tqdm/issues/1751">#1751</a> from
jaltmayerpizzorno/fix-atexit-monitor-deadlock</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/cfa4a8522e8915e5f3f29dec9cedf7a75e366e1a"><code>cfa4a85</code></a>
minor docstring updates</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/f83290ce32f424e0562d47efe2304cdb90d244d5"><code>f83290c</code></a>
Fix TMonitor deadlock at interpreter shutdown</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/59029c37ad6af57df7b49d31c0f48728280ae824"><code>59029c3</code></a>
Set name for tqdm monitor thread (<a
href="https://redirect.github.com/tqdm/tqdm/issues/1752">#1752</a>)</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/ef4a142ebd53f05b8765b969590e9a888498ab57"><code>ef4a142</code></a>
bump version, merge pull request <a
href="https://redirect.github.com/tqdm/tqdm/issues/1760">#1760</a> from
tqdm/devel</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/17f246b77dcfc29bfeaaa8bfa12ddb45557606bc"><code>17f246b</code></a>
lint warning suppression</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/c682c7b73142b1b469e698e0cf62e2963cdfb7d1"><code>c682c7b</code></a>
benchmarks: fix asv</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/fc69588dc219f30c4c59adad98355cc09933f271"><code>fc69588</code></a>
CI: migrate to pre-commit.ci</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/a31d97f821d9bf33f1b7e0a9738a3ea62baa68ca"><code>a31d97f</code></a>
more contrib.itertools</li>
<li><a
href="https://github.com/tqdm/tqdm/commit/e4d97426d6c6df91bbd681f3fe9ac98b1d704011"><code>e4d9742</code></a>
soft-deprecate tqdm.utils.envwrap -&gt; envwrap</li>
<li>Additional commits viewable in <a
href="https://github.com/tqdm/tqdm/compare/v4.67.3...v4.68.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `gevent` from 26.4.0 to 26.5.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/gevent/gevent/commit/33c560c2e26998eff1e1cea252646a17922ec5d7"><code>33c560c</code></a>
Preparing release 26.5.0</li>
<li><a
href="https://github.com/gevent/gevent/commit/7cebc52f71cd2609c4af4f5037fe630601197e14"><code>7cebc52</code></a>
ci.yml: add comments about likely problem with macOS 15/26</li>
<li><a
href="https://github.com/gevent/gevent/commit/6a9192e6fd6b2db29a70bd5a801a5d48d2d7fcdf"><code>6a9192e</code></a>
Add 315 to make-manylinux.</li>
<li><a
href="https://github.com/gevent/gevent/commit/65561dc1642304ab3cde9636146a8537ae1e7ae4"><code>65561dc</code></a>
Add change note.</li>
<li><a
href="https://github.com/gevent/gevent/commit/a65159824046b3b2da942e516c49e6b959a82548"><code>a651598</code></a>
test__threading is apparently initializing the hub on
3.15b1/ubuntu-latest/GH...</li>
<li><a
href="https://github.com/gevent/gevent/commit/c2cda32db8c33c68ee115d22bebfb3b02436298e"><code>c2cda32</code></a>
Disable some linux-specific pidfd tests because we don't use that.</li>
<li><a
href="https://github.com/gevent/gevent/commit/53371df6bef15c66f495f907d965be089d326e44"><code>53371df</code></a>
We can't do coverage on 3.15b1, it doesn't have the binary tracer needed
for ...</li>
<li><a
href="https://github.com/gevent/gevent/commit/ed9160afeb8032d9a0a1ce9cb31f817b5c63c05a"><code>ed9160a</code></a>
Initial support for Python 3.15</li>
<li><a
href="https://github.com/gevent/gevent/commit/36e8203a07ac4610102b6170161467a9595a4642"><code>36e8203</code></a>
Remove the CI badges from README.rst.</li>
<li><a
href="https://github.com/gevent/gevent/commit/21bf47d6b18caa91a151a4654b54b3145e1eb5d0"><code>21bf47d</code></a>
Disable appveyor, the windows github action runners were
successful.</li>
<li>Additional commits viewable in <a
href="https://github.com/gevent/gevent/compare/26.4.0...26.5.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `apprise` from 1.10.0 to 1.11.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/caronc/apprise/releases">apprise's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.11.0</h2>
<h2>What's Changed</h2>
<p>A big win for this release is priortization of grouped/tagged
content. Basically, this release allows you to tag multiple items and
provide a weight to them. Apprise will attempt to notify the highest
priority/weighted services first (of same level), and only if this level
fails will it try the next. Tagging is no longer just a
<code>tag</code>. It's now <code>weight:tag</code> too; for example
<code>100:friends</code> associates the weight of <code>100</code> with
the tag <code>friends</code>. You can still continue to notify friends
with your Apprise calls, but if there are weight categories, then these
will be factored into the order. Highest priority (weighted) tags have a
lower integer value (zero being the higest priority). Only the next
priority will be notified if the first fails.</p>
<p>This releae also allows you to set up a notifiation service to
gracefully fail and not have Apprise itself report a failure. This is
useful for situations where you notify several end points and you really
don't care if they're unavailable or not. Apprise wil do it's usual best
effort to send the notification, but not treat it as a failure if it
can't get through. Use <code>optional=yes</code> on your Apprise
URL.</p>
<p>Thirdly, this release introduces retries! You can now have Apprise
attempt to notify your endpoint a second, or a third, (up to 10x) tries
before giving up and deeming it unable to send the notification. Use
<code>retry=X</code> on your Apprise URL</p>
<h3>📣 New Notification Services:</h3>
<ul>
<li>Added Zoom (Incoming Webhook) Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1596">caronc/apprise#1596</a></li>
<li>Added WeChat Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1598">caronc/apprise#1598</a></li>
<li>RingCentral Support Added in <a
href="https://redirect.github.com/caronc/apprise/pull/878">caronc/apprise#878</a></li>
<li>Session Open Group Server Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1615">caronc/apprise#1615</a></li>
<li>Added HumHub Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1623">caronc/apprise#1623</a></li>
<li>Amazon Chime Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1627">caronc/apprise#1627</a></li>
<li>GroupMe Support Added in <a
href="https://redirect.github.com/caronc/apprise/pull/1629">caronc/apprise#1629</a></li>
</ul>
<h3>🐞  Bugfixes</h3>
<ul>
<li>improved robustness of windows test cases preventing others from
passing in <a
href="https://redirect.github.com/caronc/apprise/pull/1609">caronc/apprise#1609</a></li>
<li>Handle XMPP SASL SCRAM-PLUS / Channel Binding in <a
href="https://redirect.github.com/caronc/apprise/pull/1619">caronc/apprise#1619</a></li>
<li>TRACE logging during apprise init cleaned up in <a
href="https://redirect.github.com/caronc/apprise/pull/1622">caronc/apprise#1622</a></li>
<li>fixed mastodon error: AttributeError - 'list' object has no
attribute 'union' in <a
href="https://redirect.github.com/caronc/apprise/pull/1631">caronc/apprise#1631</a></li>
</ul>
<h3>💡 Features</h3>
<ul>
<li>o365:// saveToSentItems configurable - ?savesent=no in <a
href="https://redirect.github.com/caronc/apprise/pull/1599">caronc/apprise#1599</a></li>
<li>updated WhatsApp Buisness Graph API to v21 in <a
href="https://redirect.github.com/caronc/apprise/pull/1603">caronc/apprise#1603</a></li>
<li>🔥 Built in retries, escalations, priorities, and optional
service calls in <a
href="https://redirect.github.com/caronc/apprise/pull/1601">caronc/apprise#1601</a></li>
<li>Slack Template/Payload support in <a
href="https://redirect.github.com/caronc/apprise/pull/1604">caronc/apprise#1604</a></li>
<li>Added Slack workflows and trigger support in <a
href="https://redirect.github.com/caronc/apprise/pull/1605">caronc/apprise#1605</a></li>
<li>🚀 Pushover E2EE Support in <a
href="https://redirect.github.com/caronc/apprise/pull/1612">caronc/apprise#1612</a></li>
<li>WKD support added to email plugin in <a
href="https://redirect.github.com/caronc/apprise/pull/1614">caronc/apprise#1614</a>
and <a
href="https://redirect.github.com/caronc/apprise/pull/1618">caronc/apprise#1618</a></li>
<li>Amazon SNS/SES Improvements in <a
href="https://redirect.github.com/caronc/apprise/pull/1620">caronc/apprise#1620</a></li>
<li>Notifico Standalone Support Added in <a
href="https://redirect.github.com/caronc/apprise/pull/1275">caronc/apprise#1275</a></li>
</ul>
<h3>❤️ Life-Cycle Support</h3>
<ul>
<li>Update LoC badge by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/caronc/apprise/pull/1593">caronc/apprise#1593</a></li>
<li>Twitter/X migration to API v2 in <a
href="https://redirect.github.com/caronc/apprise/pull/1607">caronc/apprise#1607</a></li>
<li>improvements to workflow:// based on recent slack:// changes in <a
href="https://redirect.github.com/caronc/apprise/pull/1608">caronc/apprise#1608</a></li>
<li>🔓 Added redirect= for allowing url redirection control in <a
href="https://redirect.github.com/caronc/apprise/pull/1610">caronc/apprise#1610</a></li>
<li>mqtt:// now depends on paho-mqtt v2.1.0+ in <a
href="https://redirect.github.com/caronc/apprise/pull/1613">caronc/apprise#1613</a></li>
<li>💀 Retire msteams:// as it is no longer in service upstream in
<a
href="https://redirect.github.com/caronc/apprise/pull/1625">caronc/apprise#1625</a></li>
</ul>
<h2>Installation</h2>
<p>Apprise is available <a href="https://pypi.org/project/apprise/">on
PyPI</a> through <em>pip</em>:</p>
<pre lang="bash"><code># Install Apprise v1.11.0 from PyPI
pip install apprise==1.11.0
</code></pre>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/caronc/apprise/commit/158c4e1febc3e6093b0f357776b315a90c8a89b5"><code>158c4e1</code></a>
bumped version to v1.11.0</li>
<li><a
href="https://github.com/caronc/apprise/commit/21db421ee89b24f1716a4fce74a4404a94bbabe7"><code>21db421</code></a>
GroupMe Support Added (<a
href="https://redirect.github.com/caronc/apprise/issues/1629">#1629</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/f1e4ad2fd6659529597b1e07a1e44192faebff54"><code>f1e4ad2</code></a>
fixed mastodon error: AttributeError - 'list' object has no attribute
'union'...</li>
<li><a
href="https://github.com/caronc/apprise/commit/e17fe9dd64dd79e373877cf8ee07595cc50a01cc"><code>e17fe9d</code></a>
Amazon Chime Support (<a
href="https://redirect.github.com/caronc/apprise/issues/1627">#1627</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/dfdac59c9945385c4c75613e57d19558ec995d50"><code>dfdac59</code></a>
HumHub Support added (<a
href="https://redirect.github.com/caronc/apprise/issues/1623">#1623</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/9de0397c30a7a2e58eb57c8da995ec54eada80bc"><code>9de0397</code></a>
Notifico Standalone Support Added (<a
href="https://redirect.github.com/caronc/apprise/issues/1275">#1275</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/c3e67e61d35a1b0609d176786db1e0b2cc1287da"><code>c3e67e6</code></a>
Retired msteams:// - as it is no longer in service upstream (<a
href="https://redirect.github.com/caronc/apprise/issues/1625">#1625</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/b463f23979455b61c548a550e40a3c75f0191b30"><code>b463f23</code></a>
TRACE logging during apprise init cleaned up (<a
href="https://redirect.github.com/caronc/apprise/issues/1622">#1622</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/1e2fdeb72bd8165ad613b162794778ff1c684e67"><code>1e2fdeb</code></a>
Amazon SNS/SES Improvements (<a
href="https://redirect.github.com/caronc/apprise/issues/1620">#1620</a>)</li>
<li><a
href="https://github.com/caronc/apprise/commit/4706d0a4599a5072c8ae17375ee81862bcaac460"><code>4706d0a</code></a>
Handle XMPP SASL SCRAM-PLUS / Channel Binding (<a
href="https://redirect.github.com/caronc/apprise/issues/1619">#1619</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/caronc/apprise/compare/v1.10.0...v1.11.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `seleniumbase` from 4.48.4 to 4.49.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's
releases</a>.</em></p>
<blockquote>
<h2>4.49.7 - CDP Mode: Patch 112</h2>
<h2>CDP Mode: Patch 112</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a9a76399a3cd114f905a0a99e4abd68d3bab0d4e">Fix
RuntimeWarning: coroutine 'Connection.aclose' was never awaited</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 112 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4367">seleniumbase/SeleniumBase#4367</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.6...v4.49.7">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.6...v4.49.7</a></p>
<h2>4.49.6 - CDP Mode: Patch 111 (and more)</h2>
<h2>CDP Mode: Patch 111 (and more)</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/3cbb5772fa133619fa874e27f58f20ad6ad95dc1">Fix
RuntimeWarning: coroutine 'Event.wait' was never awaited</a>
--&gt; This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4363">seleniumbase/SeleniumBase#4363</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/e7fc1a854c6dc42b61c88b0afa883f1550983c38">Remove
the selenium-wire integration</a>
--&gt; This resolves <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4362">seleniumbase/SeleniumBase#4362</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/ed817adefb810db91b47f62d1b17faa2a3420cce">activate_cdp_mode(url)
should still open the url if already active</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/cf996bf0399b5c41ac70e1e3e84992cdf4d154be">Save
time &amp; memory by only importing sb_install if needed</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c1ab11fc1ddf2ab9077041481d0085310482ed23">Update
the CDP Mode activation sequence</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/8274d737affebf0096cb287e09d3a3a3d6b8c915">Optimize
the pytest-html report plugin</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f709444731c7c6285a31aaeaa13a2e439d51be43">Refresh
Python dependencies</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/41666ae760049966f0be96acd6aa5b04c77b8a15">Update
examples</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 111 (and more) by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4365">seleniumbase/SeleniumBase#4365</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.5...v4.49.6">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.5...v4.49.6</a></p>
<h2>4.49.5 - CDP Mode: Patch 110</h2>
<h2>CDP Mode: Patch 110</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/0b8a5ce63821fe0cb238331e21d5706c66964ef0">Update
error-handling for checking if a process is still running</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 110 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4360">seleniumbase/SeleniumBase#4360</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.4...v4.49.5">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.4...v4.49.5</a></p>
<h2>4.49.4 - CDP Mode: Patch 109</h2>
<h2>CDP Mode: Patch 109</h2>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/74ee362dc453c2a4f02a9da6469817ec936cc4bd">Handle
PermissionError in methods that use psutil</a></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/b41d33187342560fb0c0d580a0c76162b4217910">Refresh
Python dependencies</a></li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>CDP Mode: Patch 109 by <a
href="https://github.com/mdmintz"><code>@​mdmintz</code></a> in <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4358">seleniumbase/SeleniumBase#4358</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.49.3...v4.49.4">https://github.com/seleniumbase/SeleniumBase/compare/v4.49.3...v4.49.4</a></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9cd73e6698bf065e966e85457d1896cc6e4475a3"><code>9cd73e6</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4367">#4367</a>
from seleniumbase/cdp-mode-patch-112</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/c2973f391eda5eac4ecbf2a900c88797161cd88c"><code>c2973f3</code></a>
Version 4.49.7</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/a9a76399a3cd114f905a0a99e4abd68d3bab0d4e"><code>a9a7639</code></a>
Fix <code>RuntimeWarning: coroutine 'Connection.aclose' was never
awaited</code></li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/4732aafc5d24b8ad99f8cc6141b105318e9597e4"><code>4732aaf</code></a>
Merge pull request <a
href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4365">#4365</a>
from seleniumbase/cdp-mode-patch-111</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/583e6cd6b97c17dcc5f9fc52b440727b3216d6e8"><code>583e6cd</code></a>
Version 4.49.6</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/9e78a662ab7c5fef9fa80ab4357510848cf913a6"><code>9e78a66</code></a>
Officially support Python 3.15</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/f709444731c7c6285a31aaeaa13a2e439d51be43"><code>f709444</code></a>
Refresh Python dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/1c234e270d233eb8b0709276c470f36a99566d97"><code>1c234e2</code></a>
Refresh mkdocs dependencies</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/41666ae760049966f0be96acd6aa5b04c77b8a15"><code>41666ae</code></a>
Update examples</li>
<li><a
href="https://github.com/seleniumbase/SeleniumBase/commit/b8686dc65d43a2baf9a5280c2ee1b8ad6ff0a7aa"><code>b8686dc</code></a>
Update the documentation</li>
<li>Additional commits viewable in <a
href="https://github.com/seleniumbase/SeleniumBase/compare/v4.48.4...v4.49.7">compare
view</a></li>
</ul>
</details>
<br />

Updates `basedpyright` from 1.39.3 to 1.39.6
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/ad82d91ce241116737e65e660c5420dd0366f405"><code>ad82d91</code></a>
1.39.6</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/cf60738b8dbbcc89f02d097a2dfa6e91c540bd86"><code>cf60738</code></a>
fix vscode config for formatting markdown files now that we use two
formatter...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/29e303a1b0b5f401f21c28fe3ea7da4b9db09e35"><code>29e303a</code></a>
print stderr from npm commands when build fails</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/f133f3d6b9a4ef3cf2d53a929a053875e1effbe4"><code>f133f3d</code></a>
uncomment some test code which started causing a test to fail. no idea
why i ...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/f71e96bfe63f0833f3d169cf0df9208a7734929f"><code>f71e96b</code></a>
remove python 3.9 check from <code>TypeAlias4</code> test because
typeshed has dropped s...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/e4c40b76f5cb70a44825aa65da7fdaa3f32b4f85"><code>e4c40b7</code></a>
fix tests</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/d7c522bc2a8b105d206b5efce0d6dd4e2610b917"><code>d7c522b</code></a>
ruff ignore new <code>benchmarkData</code> files from upstream</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/a7cf33dce12ce64f8fb2fecf039c4422c232784a"><code>a7cf33d</code></a>
fix eslint in vscode</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/14c96beec311ff57bb3ef416ac86f886648b1adb"><code>14c96be</code></a>
fix logic for reporting invalid <code>pythonPlatform</code> detected by
the new eslint v...</li>
<li><a
href="https://github.com/DetachHead/basedpyright/commit/280802ce1b2bdbaf78a880b94355ebf702241ca9"><code>280802c</code></a>
remove remnants of webpack</li>
<li>Additional commits viewable in <a
href="https://github.com/detachhead/basedpyright/compare/v1.39.3...v1.39.6">compare
view</a></li>
</ul>
</details>
<br />

Updates `prek` from 0.3.13 to 0.4.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/releases">prek's
releases</a>.</em></p>
<blockquote>
<h2>0.4.4</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-04.</p>
<h3>✨  Highlights</h3>
<p>0.4.4 makes <code>prek run</code> easier to watch and easier to
slice.</p>
<p>Hook stream output now shows a small live preview under the running
hook in the
progress UI. Long-running hooks no longer look stuck while they are
producing
logs, and failed hooks are easier to diagnose because recent output is
already
visible before the final result.</p>
<p>The new group selector lets a single config support different
workflows. Tag
hooks with <code>groups</code>, then select or exclude those groups at
run time:</p>
<pre lang="yaml"><code>repos:
  - repo: local
    hooks:
      - id: format
        name: Format Python
        language: system
        entry: ruff format
        groups: [format, ci]
<pre><code>  - id: lint
    name: Lint Python
    language: system
    entry: ruff check
    groups: [lint, ci]
</code></pre>
<p></code></pre></p>
<pre lang="bash"><code>prek run --all-files --group ci
prek run --all-files --no-group format
</code></pre>
<p>This is useful when local development, CI, slow validation, or
project-specific
checks need different hook sets without splitting the config.</p>
<h3>💚 Sponsorship</h3>
<p>If prek saves time for you or your team, please consider sponsoring
the
project on <a href="https://github.com/sponsors/j178">GitHub
Sponsors</a>. It helps keep
new features, performance work, and maintenance moving.</p>
<h3>Enhancements</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's
changelog</a>.</em></p>
<blockquote>
<h2>0.4.4</h2>
<p>Released on 2026-06-04.</p>
<h3>Highlights</h3>
<p>0.4.4 makes <code>prek run</code> easier to watch and easier to
slice.</p>
<p>Hook stream output now shows a small live preview under the running
hook in the
progress UI. Long-running hooks no longer look stuck while they are
producing
logs, and failed hooks are easier to diagnose because recent output is
already
visible before the final result.</p>
<p>The new group selector lets a single config support different
workflows. Tag
hooks with <code>groups</code>, then select or exclude those groups at
run time:</p>
<pre lang="yaml"><code>repos:
  - repo: local
    hooks:
      - id: format
        name: Format Python
        language: system
        entry: ruff format
        groups: [format, ci]
<pre><code>  - id: lint
    name: Lint Python
    language: system
    entry: ruff check
    groups: [lint, ci]
</code></pre>
<p></code></pre></p>
<pre lang="bash"><code>prek run --all-files --group ci
prek run --all-files --no-group format
</code></pre>
<p>This is useful when local development, CI, slow validation, or
project-specific
checks need different hook sets without splitting the config.</p>
<h3>Enhancements</h3>
<ul>
<li>Add hook group filters to <code>prek run</code> (<a
href="https://redirect.github.com/j178/prek/pull/2141">#2141</a>)</li>
<li>Delay hook output preview rendering (<a
href="https://redirect.github.com/j178/prek/pull/2140">#2140</a>)</li>
<li>Stream hook output in progress UI (<a
href="https://redirect.github.com/j178/prek/pull/2136">#2136</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>Fix intent-to-add stash restore (<a
href="https://redirect.github.com/j178/prek/pull/2143">#2143</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/j178/prek/commit/f44270e63f839011442ac96420cedc6aec3d8dfa"><code>f44270e</code></a>
Bump version 0.4.4 (<a
href="https://redirect.github.com/j178/prek/issues/2148">#2148</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/da457c57b5602b815dceb9ba115ad164f5e1315c"><code>da457c5</code></a>
Document hook stage file input (<a
href="https://redirect.github.com/j178/prek/issues/2147">#2147</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/0fa29294fad36956c5099d8b6cb790d6122ab9ac"><code>0fa2929</code></a>
Add hook group filters to <code>prek run</code> (<a
href="https://redirect.github.com/j178/prek/issues/2141">#2141</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/9b0047ffb3c1f255edac769ce56667aad0f935dc"><code>9b0047f</code></a>
Fix intent-to-add stash restore (<a
href="https://redirect.github.com/j178/prek/issues/2143">#2143</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/00b2520f41c5722db0b3be684be245320c4dec37"><code>00b2520</code></a>
Delay hook output preview rendering (<a
href="https://redirect.github.com/j178/prek/issues/2140">#2140</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/a54fdf0935e18d3e35f848cb40c18ae96220288b"><code>a54fdf0</code></a>
Simplify hook output preview rendering (<a
href="https://redirect.github.com/j178/prek/issues/2139">#2139</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ab7165d5cd06be239766ab25426d4459d51ec5e4"><code>ab7165d</code></a>
Stream hook output in progress UI (<a
href="https://redirect.github.com/j178/prek/issues/2136">#2136</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/f60958443fa8a9928924aa9cfcbb6d3412d9ef71"><code>f609584</code></a>
Remove unpinned dotnet test (<a
href="https://redirect.github.com/j178/prek/issues/2137">#2137</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/ce0d8b34de8800f713de19a108dfcf70a95b2a62"><code>ce0d8b3</code></a>
Update Rust to 1.96 (<a
href="https://redirect.github.com/j178/prek/issues/2134">#2134</a>)</li>
<li><a
href="https://github.com/j178/prek/commit/1815fc50cca664fa48c96494ec7d4aa7df72a135"><code>1815fc5</code></a>
Update PyPI Downloads badge to dynamic JSON</li>
<li>Additional commits viewable in <a
href="https://github.com/j178/prek/compare/v0.3.13...v0.4.4">compare
view</a></li>
</ul>
</details>
<br />

Updates `ruff` from 0.15.12 to 0.15.16
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.15.16</h2>
<h2>Release Notes</h2>
<p>Released on 2026-06-04.</p>
<h3>Preview features</h3>
<ul>
<li>[<code>flake8-async</code>] Implement
<code>yield-in-context-manager-in-async-generator</code>
(<code>ASYNC119</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24644">#24644</a>)</li>
<li>[<code>pylint</code>] Narrow diagnostic range and exclude cases
without exception handlers (<code>PLW0717</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25440">#25440</a>)</li>
<li>[<code>ruff</code>] Treat <code>yield</code> before
<code>break</code> from a terminal loop as terminal
(<code>RUF075</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25447">#25447</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>[<code>eradicate</code>] Avoid flagging <code>ruff:ignore</code>
comments as code (<code>ERA001</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25537">#25537</a>)</li>
<li>[<code>eradicate</code>] Fix <code>ERA001</code>/<code>RUF100</code>
conflict when <code>noqa</code> is on commented-out code (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25414">#25414</a>)</li>
<li>[<code>pyflakes</code>] Avoid removing the <code>format</code> call
when it would change behavior (<code>F523</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25320">#25320</a>)</li>
<li>[<code>pylint</code>] Avoid syntax errors in invalid character
replacements in f-strings before Python 3.12 (<code>PLE2510</code>,
<code>PLE2512</code>, <code>PLE2513</code>, <code>PLE2514</code>,
<code>PLE2515</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25544">#25544</a>)</li>
<li>[<code>pyupgrade</code>] Avoid converting <code>format</code> calls
with more kinds of side effects (<code>UP032</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25484">#25484</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pytest-style</code>] Avoid fixes for ambiguous
<code>argnames</code> and <code>argvalues</code> combinations
(<code>PT006</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24776">#24776</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Drop excess capacity from statement suites during parsing (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25368">#25368</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>[<code>pydocstyle</code>] Improve discoverability of rules enabled
for each convention (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24973">#24973</a>)</li>
<li>[<code>ruff</code>] Restore example code for Python versions before
3.15 (<code>RUF017</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25439">#25439</a>)</li>
<li>Fix typo <code>bin/active</code> → <code>bin/activate</code> in
tutorial (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25473">#25473</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Shrink additional parser AST collections (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25465">#25465</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/Redslayer112"><code>@​Redslayer112</code></a></li>
<li><a
href="https://github.com/koriyoshi2041"><code>@​koriyoshi2041</code></a></li>
<li><a
href="https://github.com/George-Ogden"><code>@​George-Ogden</code></a></li>
<li><a
href="https://github.com/TejasAmle"><code>@​TejasAmle</code></a></li>
<li><a
href="https://github.com/anishgirianish"><code>@​anishgirianish</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a
href="https://github.com/loganrosen"><code>@​loganrosen</code></a></li>
<li><a
href="https://github.com/RafaelJohn9"><code>@​RafaelJohn9</code></a></li>
<li><a
href="https://github.com/adityasingh2400"><code>@​adityasingh2400</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's
changelog</a>.</em></p>
<blockquote>
<h2>0.15.16</h2>
<p>Released on 2026-06-04.</p>
<h3>Preview features</h3>
<ul>
<li>[<code>flake8-async</code>] Implement
<code>yield-in-context-manager-in-async-generator</code>
(<code>ASYNC119</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24644">#24644</a>)</li>
<li>[<code>pylint</code>] Narrow diagnostic range and exclude cases
without exception handlers (<code>PLW0717</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25440">#25440</a>)</li>
<li>[<code>ruff</code>] Treat <code>yield</code> before
<code>break</code> from a terminal loop as terminal
(<code>RUF075</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25447">#25447</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>[<code>eradicate</code>] Avoid flagging <code>ruff:ignore</code>
comments as code (<code>ERA001</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25537">#25537</a>)</li>
<li>[<code>eradicate</code>] Fix <code>ERA001</code>/<code>RUF100</code>
conflict when <code>noqa</code> is on commented-out code (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25414">#25414</a>)</li>
<li>[<code>pyflakes</code>] Avoid removing the <code>format</code> call
when it would change behavior (<code>F523</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25320">#25320</a>)</li>
<li>[<code>pylint</code>] Avoid syntax errors in invalid character
replacements in f-strings before Python 3.12 (<code>PLE2510</code>,
<code>PLE2512</code>, <code>PLE2513</code>, <code>PLE2514</code>,
<code>PLE2515</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25544">#25544</a>)</li>
<li>[<code>pyupgrade</code>] Avoid converting <code>format</code> calls
with more kinds of side effects (<code>UP032</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25484">#25484</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-pytest-style</code>] Avoid fixes for ambiguous
<code>argnames</code> and <code>argvalues</code> combinations
(<code>PT006</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24776">#24776</a>)</li>
</ul>
<h3>Performance</h3>
<ul>
<li>Drop excess capacity from statement suites during parsing (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25368">#25368</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>[<code>pydocstyle</code>] Improve discoverability of rules enabled
for each convention (<a
href="https://redirect.github.com/astral-sh/ruff/pull/24973">#24973</a>)</li>
<li>[<code>ruff</code>] Restore example code for Python versions before
3.15 (<code>RUF017</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25439">#25439</a>)</li>
<li>Fix typo <code>bin/active</code> → <code>bin/activate</code> in
tutorial (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25473">#25473</a>)</li>
</ul>
<h3>Other changes</h3>
<ul>
<li>Shrink additional parser AST collections (<a
href="https://redirect.github.com/astral-sh/ruff/pull/25465">#25465</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a
href="https://github.com/Redslayer112"><code>@​Redslayer112</code></a></li>
<li><a
href="https://github.com/koriyoshi2041"><code>@​koriyoshi2041</code></a></li>
<li><a
href="https://github.com/George-Ogden"><code>@​George-Ogden</code></a></li>
<li><a
href="https://github.com/TejasAmle"><code>@​TejasAmle</code></a></li>
<li><a
href="https://github.com/anishgirianish"><code>@​anishgirianish</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a
href="https://github.com/loganrosen"><code>@​loganrosen</code></a></li>
<li><a
href="https://github.com/RafaelJohn9"><code>@​RafaelJohn9</code></a></li>
<li><a
href="https://github.com/adityasingh2400"><code>@​adityasingh2400</code></a></li>
</ul>
<h2>0.15.15</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/ruff/commit/6c498ab5394edc5622d7f348e12956bf86203716"><code>6c498ab</code></a>
Bump 0.15.16 (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25635">#25635</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/e51e132831c4e1c4a5ac00fca4c9256354ab99bf"><code>e51e132</code></a>
[<code>flake8-async</code>] Implement
<code>yield-in-context-manager-in-async-generator</code> (`AS...</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/7c6dcd9f2611999c449143d241c582dedf287964"><code>7c6dcd9</code></a>
[ty] Add caching for pattern match narrowing (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25613">#25613</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/27058fc071b542bf06395ba89cabed061d313ca6"><code>27058fc</code></a>
[ty] Compact retained definition and expression identities (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25606">#25606</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/bf80d05f007c939799f530c9e775ed9449f5b2eb"><code>bf80d05</code></a>
Fix CODEOWNERS syntax (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25622">#25622</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/10ccd511e94a81d1e836b174f1c553a73ff3f1b3"><code>10ccd51</code></a>
Shrink additional parser AST collections (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25465">#25465</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/0d7135f4d23e7f4d8404daed16b9ef11d14f3fb9"><code>0d7135f</code></a>
[ty] Upgrade Salsa (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25545">#25545</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/49493a3cea83a08fa9aa143695017c816a540f1d"><code>49493a3</code></a>
[ty] Show type alias value on hover (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25381">#25381</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/85207d3b7657a84252f266766cb0d56034dc21cc"><code>85207d3</code></a>
[ty] sys.implementation.version is not sys.version_info (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25608">#25608</a>)</li>
<li><a
href="https://github.com/astral-sh/ruff/commit/a8a0614348c1fcf47fc9b666eff61a103914d520"><code>a8a0614</code></a>
[ty] Avoid retaining duplicate function signatures (<a
href="https://redirect.github.com/astral-sh/ruff/issues/25609">#25609</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.15.12...0.15.16">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-09 20:53:20 -04:00
dependabot[bot]andCaliBrain 8c86cdc1dd Bump the npm-deps group across 1 directory with 14 updates (#1043)
Bumps the npm-deps group with 13 updates in the /src/frontend directory:

| Package | From | To |
| --- | --- | --- |
|
[@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)
| `4.2.4` | `4.3.0` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) |
`19.2.6` | `19.2.7` |
|
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
| `19.2.14` | `19.2.16` |
|
[react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom)
| `19.2.6` | `19.2.7` |
|
[react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)
| `7.15.0` | `7.16.0` |
|
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
| `25.6.2` | `25.9.1` |
|
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react)
| `6.0.1` | `6.0.2` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) |
`6.12.1` | `6.15.0` |
| [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) |
`0.48.0` | `0.53.0` |
| [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) |
`1.63.0` | `1.68.0` |
| [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) | `0.22.1`
| `0.23.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) |
`8.0.11` | `8.0.16` |
|
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)
| `4.1.5` | `4.1.8` |


Updates `@tailwindcss/vite` from 4.2.4 to 4.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">@​tailwindcss/vite's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<h3>Added</h3>
<ul>
<li>Add <code>@container-size</code> utility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18901">#18901</a>)</li>
<li>Add <code>scrollbar-{auto,thin,none}</code> utilities for
<code>scrollbar-width</code>, and <code>scrollbar-thumb-*</code> /
<code>scrollbar-track-*</code> color utilities for
<code>scrollbar-color</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19981">#19981</a>,
<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20019">#20019</a>)</li>
<li>Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20018">#20018</a>)</li>
<li>Add <code>zoom-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20020">#20020</a>)</li>
<li>Add <code>tab-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20022">#20022</a>)</li>
<li>Allow using <code>@variant</code> with stacked variants (e.g.
<code>@variant hover:focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Allow using <code>@variant</code> with compound variants (e.g.
<code>@variant hover, focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> for functional <code>@utility</code>
definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19989">#19989</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure <code>@plugin</code> resolves package JavaScript entries
instead of browser CSS entries when using <code>@tailwindcss/vite</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19949">#19949</a>)</li>
<li>Fix relative <code>@import</code> and <code>@plugin</code> paths
resolving from the wrong directory when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19965">#19965</a>)</li>
<li>Ensure CSS files containing <code>@variant</code> are processed by
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19966">#19966</a>)</li>
<li>Resolve imports relative to <code>base</code> when
<code>result.opts.from</code> is not provided when using
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19980">#19980</a>)</li>
<li>Canonicalization: preserve significant <code>_</code> whitespace in
arbitrary values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: add parentheses when removing whitespace from
arbitrary values would hurt readability (e.g.
<code>w-[calc(100%---spacing(60))]</code> →
<code>w-[calc(100%-(--spacing(60)))]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: preserve the original unit in arbitrary values
instead of normalizing to base units (e.g. <code>-mt-[20in]</code> →
<code>mt-[-20in]</code>, not <code>mt-[-1920px]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19988">#19988</a>)</li>
<li>Canonicalization: migrate arbitrary <code>:has()</code> variants
from <code>[&amp;:has(…)]</code> to <code>has-[…]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19991">#19991</a>)</li>
<li>Upgrade: don’t migrate inline <code>style</code> attributes (e.g.
<code>style=&quot;flex-grow: 1&quot;</code> →
<code>style=&quot;flex-grow: 1&quot;</code>, not <code>style=&quot;grow:
1&quot;</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19918">#19918</a>)</li>
<li>Allow multiple <code>@utility</code> definitions with the same name
but different value types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19777">#19777</a>)</li>
<li>Export missing <code>PluginWithConfig</code> type from
<code>tailwindcss/plugin</code> to fix errors when inferring plugin
config types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19707">#19707</a>)</li>
<li>Ensure <code>start</code> and <code>end</code> legacy utilities
without values do not generate CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20003">#20003</a>)</li>
<li>Ensure <code>--value(…)</code> is required in functional
<code>@utility</code> definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20005">#20005</a>)</li>
<li>Canonicalization: preserve required whitespace around operators in
negated arbitrary values (e.g. <code>-left-[(var(--a)+var(--b))]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20011">#20011</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md">@​tailwindcss/vite's
changelog</a>.</em></p>
<blockquote>
<h2>[4.3.0] - 2026-05-08</h2>
<h3>Added</h3>
<ul>
<li>Add <code>@container-size</code> utility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18901">#18901</a>)</li>
<li>Add <code>scrollbar-{auto,thin,none}</code> utilities for
<code>scrollbar-width</code>, and <code>scrollbar-thumb-*</code> /
<code>scrollbar-track-*</code> color utilities for
<code>scrollbar-color</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19981">#19981</a>,
<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20019">#20019</a>)</li>
<li>Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20018">#20018</a>)</li>
<li>Add <code>zoom-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20020">#20020</a>)</li>
<li>Add <code>tab-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20022">#20022</a>)</li>
<li>Allow using <code>@variant</code> with stacked variants (e.g.
<code>@variant hover:focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Allow using <code>@variant</code> with compound variants (e.g.
<code>@variant hover, focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> for functional <code>@utility</code>
definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19989">#19989</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure <code>@plugin</code> resolves package JavaScript entries
instead of browser CSS entries when using <code>@tailwindcss/vite</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19949">#19949</a>)</li>
<li>Fix relative <code>@import</code> and <code>@plugin</code> paths
resolving from the wrong directory when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19965">#19965</a>)</li>
<li>Ensure CSS files containing <code>@variant</code> are processed by
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19966">#19966</a>)</li>
<li>Resolve imports relative to <code>base</code> when
<code>result.opts.from</code> is not provided when using
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19980">#19980</a>)</li>
<li>Canonicalization: preserve significant <code>_</code> whitespace in
arbitrary values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: add parentheses when removing whitespace from
arbitrary values would hurt readability (e.g.
<code>w-[calc(100%---spacing(60))]</code> →
<code>w-[calc(100%-(--spacing(60)))]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: preserve the original unit in arbitrary values
instead of normalizing to base units (e.g. <code>-mt-[20in]</code> →
<code>mt-[-20in]</code>, not <code>mt-[-1920px]</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19988">#19988</a>)</li>
<li>Canonicalization: migrate arbitrary <code>:has()</code> variants
from <code>[&amp;:has(…)]</code> to <code>has-[…]</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19991">#19991</a>)</li>
<li>Upgrade: don’t migrate inline <code>style</code> attributes (e.g.
<code>style=&quot;flex-grow: 1&quot;</code> →
<code>style=&quot;flex-grow: 1&quot;</code>, not <code>style=&quot;grow:
1&quot;</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19918">#19918</a>)</li>
<li>Allow multiple <code>@utility</code> definitions with the same name
but different value types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19777">#19777</a>)</li>
<li>Export missing <code>PluginWithConfig</code> type from
<code>tailwindcss/plugin</code> to fix errors when inferring plugin
config types (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19707">#19707</a>)</li>
<li>Ensure <code>start</code> and <code>end</code> legacy utilities
without values do not generate CSS (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20003">#20003</a>)</li>
<li>Ensure <code>--value(…)</code> is required in functional
<code>@utility</code> definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20005">#20005</a>)</li>
<li>Canonicalization: preserve required whitespace around operators in
negated arbitrary values (e.g. <code>-left-[(var(--a)+var(--b))]</code>)
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20011">#20011</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/588bd7371f4cae96426e1387819b7fd1d99765f9"><code>588bd73</code></a>
4.3.0 (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/20023">#20023</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/d194d4c3e656313421f1cfa1954db8f58eec0fcd"><code>d194d4c</code></a>
docs: fix various typos in comments and documentation (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/19878">#19878</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/db27049caaae08978995f25b61f8336f543a4640"><code>db27049</code></a>
fix(<code>@​tailwindcss/vite</code>): include <a
href="https://github.com/variant"><code>@​variant</code></a> in feature
detection (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/19966">#19966</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/5a799900d4b43ca4902398a38c6f0a5b37a98ed9"><code>5a79990</code></a>
Always resolve relative files, relative to the current .css file (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/19965">#19965</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss/commit/f3fdda2a5cb9de50c897c79003aa58182cd9269b"><code>f3fdda2</code></a>
fix(vite): avoid resolving JS plugins to browser CSS entries (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/19949">#19949</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `react` from 19.2.6 to 19.2.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/releases">react's
releases</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6
(<a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>
by <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/facebook/react/commit/6117d7cca4906492c51fe6a03381e35adfd86e7d"><code>6117d7c</code></a>
Version 19.2.7 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/36591">#36591</a>)</li>
<li>See full diff in <a
href="https://github.com/facebook/react/commits/v19.2.7/packages/react">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for react since your current version.</p>
</details>
<br />

Updates `@types/react` from 19.2.14 to 19.2.16
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `react-dom` from 19.2.6 to 19.2.7
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/releases">react-dom's
releases</a>.</em></p>
<blockquote>
<h2>19.2.7 (June 1st, 2026)</h2>
<h2>React Server Components</h2>
<ul>
<li>Fixed missing <code>FormData</code> entries in Server Actions which
regressed in 19.2.6
(<a
href="https://redirect.github.com/facebook/react/pull/36566">#36566</a>
by <a
href="https://github.com/unstubbable"><code>@​unstubbable</code></a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/facebook/react/commit/6117d7cca4906492c51fe6a03381e35adfd86e7d"><code>6117d7c</code></a>
Version 19.2.7 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/36591">#36591</a>)</li>
<li>See full diff in <a
href="https://github.com/facebook/react/commits/v19.2.7/packages/react-dom">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for react-dom since your current version.</p>
</details>
<br />

Updates `react-router-dom` from 7.15.0 to 7.16.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md">react-router-dom's
changelog</a>.</em></p>
<blockquote>
<h2>v7.16.0</h2>
<h3>Patch Changes</h3>
<ul>
<li>Remove stale/invalid <code>unpkg</code> field from
<code>package.json</code>. This was removed from other packages with the
release of v7 but missed in the <code>react-router-dom</code> re-export
package (<a
href="https://redirect.github.com/remix-run/react-router/pull/15075">#15075</a>)</li>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.16.0"><code>react-router@7.16.0</code></a></li>
</ul>
</li>
</ul>
<h2>v7.15.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>Updated dependencies:
<ul>
<li><a
href="https://github.com/remix-run/react-router/releases/tag/react-router@7.15.1"><code>react-router@7.15.1</code></a></li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/8984d23f86ca7ae5655711744b77816090bda4e6"><code>8984d23</code></a>
Release v7.16.0 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15105">#15105</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/3ed77afcde0ad9aea79f1afe5f05a700b201f289"><code>3ed77af</code></a>
chore: format</li>
<li><a
href="https://github.com/remix-run/react-router/commit/e96962bc6159a2290632849b55872a3878753342"><code>e96962b</code></a>
fix: remove stale unpkg field from react-router-dom (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15075">#15075</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/587d08fca6ca61e00f44c1eda95bf6e6a9ab76ef"><code>587d08f</code></a>
Release v7.15.1 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom/issues/15038">#15038</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router-dom@7.16.0/packages/react-router-dom">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/node` from 25.6.2 to 25.9.1
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react` from 19.2.14 to 19.2.16
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `@vitejs/plugin-react` from 6.0.1 to 6.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/releases">@​vitejs/plugin-react's
releases</a>.</em></p>
<blockquote>
<h2>plugin-react@6.0.2</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@​vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.0.2 (2026-05-14)</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/6535b55e956b425e6650ffc2cc98fd23cca1d231"><code>6535b55</code></a>
release: plugin-react@6.0.2</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/bf0e43b756e3be81f8572d59727c218311f431ef"><code>bf0e43b</code></a>
feat(react): whitelist debugging-options (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1189">#1189</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/3bd1f08ae0b82ee0e96feb2ff265e61c6fe74b54"><code>3bd1f08</code></a>
feat: use carets for rolldown versions (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1216">#1216</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/2b8df67323265d1ff5ddf47b2db9ab0b9de5c688"><code>2b8df67</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1218">#1218</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/8fa9619e1b1f51b079f4c1df6bcf076dcafc5aed"><code>8fa9619</code></a>
fix(deps): update react 19.2.6 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1211">#1211</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/a4296ad2995a8d493528b8d5450a1209de2943cb"><code>a4296ad</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1209">#1209</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/323ccd72576be636b50baa7d9ce816cc94d5991e"><code>323ccd7</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1196">#1196</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/a7506e105df00cdadc58c0aecc4512d8cfdd9765"><code>a7506e1</code></a>
chore(deps): update vite 8.0.10 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1198">#1198</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/02cff2a0cf5c7e9792b1612baa380228f5e4d3c1"><code>02cff2a</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1184">#1184</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/4b9c890cdb21078ac45a86873b24f7e8613b8526"><code>4b9c890</code></a>
fix(deps): update react 19.2.5 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1181">#1181</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.2/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<br />

Updates `knip` from 6.12.1 to 6.15.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/webpro-nl/knip/releases">knip's
releases</a>.</em></p>
<blockquote>
<h2>Release 6.15.0</h2>
<ul>
<li>Report exported type used only in inferred-return function body
(resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1765">#1765</a>)
(2413408753f7abc7a9dfdba520990afd18c53ee0)</li>
<li>Work that EXPORTS.md again
(7e13451fab7ad85362fb63a4715ea450690aedef)</li>
<li>Update npmx ecosystem snapshot
(dfc401145a880f156c66eb83ea1622a99540304a)</li>
<li>Link <code>dependencies</code> key with notes (closes <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1764">#1764</a>)
(e3e66cea9e946558940bf8705129efea3f23b3ba)</li>
<li>Resolve tsconfig paths when loading plugin configs (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1762">#1762</a>)
(0177c7466559e2ae99b5e1cd1e3a8043ca494edc) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Avoid caching failed plugin config loads (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1768">#1768</a>)
(5e201cde9b1ba2568ead2ae790ab888c966828ae) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Resolve extensionless .sass imports in SCSS compiler (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1770">#1770</a>)
(30c22835383b2355787cc2a871b22de80ff75544) - thanks <a
href="https://github.com/sebacardello"><code>@​sebacardello</code></a>!</li>
<li>fix(vite): detect inline module script entry points in index.html
(<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1772">#1772</a>)
(51f4eddc9e1b2fed1ba25e81fc596e9fb514ce01) - thanks <a
href="https://github.com/lucas-spin"><code>@​lucas-spin</code></a>!</li>
<li>Harden vite inline module script import detection
(b8abcfd2f4f5486aea08a934514bc55de86be030)</li>
<li>Use RecordableHistogram for timerified function stats
(d575c6905704af1b0b4620edd874fc09bc86ed28)</li>
<li>Add orval plugin (resolves <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1751">#1751</a>)
(4c82aa82c2a02fbda27a316389f210d11621f8cb)</li>
<li>Add treatTagHintsAsErrors and --no-tag-hints (resolves <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1767">#1767</a>)
(4b6a573e0c1e0daf65c76c32f7336ea71db6bb64)</li>
<li>Add nano-spawn plugin (resolves <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1769">#1769</a>)
(b2cad06dfd9958485537c5545c6c497fc8823ac3)</li>
<li>Simplify glob cache validation and ignore-list assembly
(df1a9603a5ea8ed7bad9588bf13672cedf37c90e)</li>
<li>Dedupe ignore-pattern collection and dependency fixing
(d49b626ad6736d7123d44568ef8c42a3e1d28aa3)</li>
<li>Simplify installed-binaries collection in manifest metadata
(55143941eebbc8dac12c79b77c1f65a8b61dfbef)</li>
<li>Flatten control flow in ConfigurationChief
(010d5709b0f9a3adc5ebe6e7169b9f5c4f29abc5)</li>
<li>Inline trivial installed-binaries and types-included accessors
(b5afb9f29e3474eee4bf276c1de83cb0682a5663)</li>
<li>Format (eb4b178d5d90a719cdc576d644766f8f95a47876)</li>
<li>Replace <code>@​wdio/types</code> dev dep with inline types
(a3747d61ee0e594854e5da0ca6cb7597e0096b99)</li>
<li>Bump dependencies (822ab3905cb7b5a216404231607a7820105930a2)</li>
<li>Work AGENTS.md, etcetera
(361bd4803934a01e01b08170565f8374e4e49eb2)</li>
<li>Remove rootDirs workaround resolved by oxc-resolver 11.20.0
(e190a9fec22db41975cf9568a31970a05c86e66b)</li>
<li>Add nuxt no-root-tsconfig fixture guarding alias resolution
(e3e5bc94d5f7b6ffdbc89b18d7c8d5acbb5a9008)</li>
<li>Allow extra args for release-it
(f9c59952fa2c8c4c13bd42edc0935610900d1980)</li>
<li>Add <a href="https://github.com/vercel"><code>@​vercel</code></a> as
platinum sponsor (c4c06a9149c986680f0d1aa74b57a46ff1f88601)</li>
<li>Overhaul &amp; improve --trace functionailty
(60df0b05f364c8d841c0f784a06bab2a3215a32f)</li>
<li>Re-gen plugins.md (0f9d044d312053154498a562e3a9422a4f44afe6)</li>
</ul>
<h2>Release 6.14.2</h2>
<ul>
<li>Fix vscode-knip build: pin native oxc bindings to bundled JS version
(1b45a4103312c9c059560ae2e1eac25d86b4e2ac)</li>
<li>Release vscode-knip@2.1.5
(328892eb04e65b4702e1ef2303db3156b8f2e1a3)</li>
<li>Fix Astro plugin to support both possible middleware entry points
(<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1749">#1749</a>)
(33e0cc1a530a8cf5b6b05c8b3a3ca55f8fce8a75) - thanks <a
href="https://github.com/schmalz-dmi"><code>@​schmalz-dmi</code></a>!</li>
<li>Fix LICENSE link (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1760">#1760</a>)
(829620f9077ddea086a610c279c7c1250dd66e11) - thanks <a
href="https://github.com/vortispy"><code>@​vortispy</code></a>!</li>
<li>Fix GraphQL Codegen script config dependencies (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1756">#1756</a>)
(e841c6355e7eff240e74010bfd2be8bbb22ff2b6) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Set pnpm config via env vars, disable verify-deps in ecosystem tests
(53c12248cc3e79fd79f3efde691d463fc795c40f)</li>
<li>Update slonik ecosystem snapshot
(f18410b34c8554364a9f003660bebae5e826de57)</li>
<li>Fix Serverless TypeScript plugin dependencies (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1757">#1757</a>)
(ebde7f8f3e3004db7f51fb5d60a0bdc2452116ef) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Fix extended tsconfig type dependency attribution (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1758">#1758</a>)
(f600b09e562317a37844ed8cdf1b9b46e06c9405) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Fix Bun binary dependency tracking (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1759">#1759</a>)
(1b289239f35ff2912195b7e39a96c667c54c1fc5) - thanks <a
href="https://github.com/jakeleventhal"><code>@​jakeleventhal</code></a>!</li>
<li>Detect Babel plugins/presets in Vite plugin options (resolve <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1761">#1761</a>)
(2753d6910743a12a207fca81cb8325c00803963a)</li>
</ul>
<h2>Release 6.14.1</h2>
<ul>
<li>Detect dynamic imports in Svelte compiler (<a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1747">#1747</a>)
(e1c1b1705f96ed7d6ac537a7969cbd07d238246a) - thanks <a
href="https://github.com/jinhyuk9714"><code>@​jinhyuk9714</code></a>!</li>
<li>Detect dynamic import attributes; share import matcher with
Astro-MDX (9dae64166bbc45be1abeb8d741127d109d48d351)</li>
<li>Work the docs (close <a
href="https://github.com/webpro-nl/knip/tree/HEAD/packages/knip/issues/1746">#1746</a>)
(919cba2f11d1979b854c7abaaca8992ee8b08e23)</li>
</ul>
<h2>Release 6.14.0</h2>
<ul>
<li>Resolve imports satisfied via transitive peerDeps (d654ec74d)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/webpro-nl/knip/commit/3f3769e37b75e3d35e3713e8435735adc00df52b"><code>3f3769e</code></a>
Release knip@6.15.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/60df0b05f364c8d841c0f784a06bab2a3215a32f"><code>60df0b0</code></a>
Overhaul &amp; improve --trace functionailty</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/e3e5bc94d5f7b6ffdbc89b18d7c8d5acbb5a9008"><code>e3e5bc9</code></a>
Add nuxt no-root-tsconfig fixture guarding alias resolution</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/e190a9fec22db41975cf9568a31970a05c86e66b"><code>e190a9f</code></a>
Remove rootDirs workaround resolved by oxc-resolver 11.20.0</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/822ab3905cb7b5a216404231607a7820105930a2"><code>822ab39</code></a>
Bump dependencies</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/a3747d61ee0e594854e5da0ca6cb7597e0096b99"><code>a3747d6</code></a>
Replace <code>@​wdio/types</code> dev dep with inline types</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/eb4b178d5d90a719cdc576d644766f8f95a47876"><code>eb4b178</code></a>
Format</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/b5afb9f29e3474eee4bf276c1de83cb0682a5663"><code>b5afb9f</code></a>
Inline trivial installed-binaries and types-included accessors</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/010d5709b0f9a3adc5ebe6e7169b9f5c4f29abc5"><code>010d570</code></a>
Flatten control flow in ConfigurationChief</li>
<li><a
href="https://github.com/webpro-nl/knip/commit/55143941eebbc8dac12c79b77c1f65a8b61dfbef"><code>5514394</code></a>
Simplify installed-binaries collection in manifest metadata</li>
<li>Additional commits viewable in <a
href="https://github.com/webpro-nl/knip/commits/knip@6.15.0/packages/knip">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxfmt` from 0.48.0 to 0.53.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/964a7580840f394d67c149ea083e35a1e74c128f"><code>964a758</code></a>
release(apps): oxlint v1.68.0 &amp;&amp; oxfmt v0.53.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22883">#22883</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/68b455d84f0b18bd6646cfe4f9babb12ec4fc448"><code>68b455d</code></a>
release(apps): oxlint v1.67.0 &amp;&amp; oxfmt v0.52.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22735">#22735</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/16b8058cd6fd55472cb3a225852ca22db24bb461"><code>16b8058</code></a>
feat(oxfmt): Support <code>vite-plus/resolveConfig</code> for
vite.config.ts (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22454">#22454</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/557020642e27b948e46f73754b82bee452a82f32"><code>5570206</code></a>
release(apps): oxlint v1.66.0 &amp;&amp; oxfmt v0.51.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22528">#22528</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/25e5cbc76f887cf5c0c2bdfbef8d4a74fd1ce87d"><code>25e5cbc</code></a>
release(apps): oxlint v1.65.0 &amp;&amp; oxfmt v0.50.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22458">#22458</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/43b997847b76bfbc35e83738296330a9a33de4e4"><code>43b9978</code></a>
fix(formatter/sort_imports): Treat subpath imports as internal (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22440">#22440</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/d652a556196178515a3c1ea6d25a832c74961d02"><code>d652a55</code></a>
release(apps): oxlint v1.64.0 &amp;&amp; oxfmt v0.49.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22318">#22318</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/6e8e8185c0a3d653bb90dff051ec7d4558793752"><code>6e8e818</code></a>
feat(oxfmt): Experimental .svelte support (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/21700">#21700</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/330fe31f826b7d4ae11ae49ba50e2b2ab2bdc6f1"><code>330fe31</code></a>
refactor(config): Update doc comment for <code>GlobSet</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22197">#22197</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/fb3067ca2bafbbf7d75b058788202dc16d994f3e"><code>fb3067c</code></a>
refactor(oxfmt): use shared GlobSet for overrides (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt/issues/22147">#22147</a>)</li>
<li>See full diff in <a
href="https://github.com/oxc-project/oxc/commits/oxfmt_v0.53.0/npm/oxfmt">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint` from 1.63.0 to 1.68.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/releases">oxlint's
releases</a>.</em></p>
<blockquote>
<h2>oxlint v1.27.0 &amp;&amp; oxfmt v0.12.0</h2>
<h1>Oxlint v1.27.0</h1>
<h3>🚀 Features</h3>
<ul>
<li>222a8f0 linter/plugins: Implement
<code>SourceCode#isSpaceBetween</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15498">#15498</a>)
(overlookmotel)</li>
<li>2f9735d linter/plugins: Implement
<code>context.languageOptions</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15486">#15486</a>)
(overlookmotel)</li>
<li>bc731ff linter/plugins: Stub out all <code>Context</code> APIs (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15479">#15479</a>)
(overlookmotel)</li>
<li>5822cb4 linter/plugins: Add <code>extend</code> method to
<code>FILE_CONTEXT</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15477">#15477</a>)
(overlookmotel)</li>
<li>7b1e6f3 apps: Add pure rust binaries and release to github (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15469">#15469</a>)
(Boshen)</li>
<li>2a89b43 linter: Introduce debug assertions after fixes to assert
validity (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15389">#15389</a>)
(camc314)</li>
<li>ad3c45a editor: Add <code>oxc.path.node</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15040">#15040</a>)
(Sysix)</li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>6f3cd77 linter/no-var: Incorrect warning for blocks (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15504">#15504</a>)
(Hamir Mahal)</li>
<li>6957fb9 linter/plugins: Do not allow access to
<code>Context#id</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15489">#15489</a>)
(overlookmotel)</li>
<li>7409630 linter/plugins: Allow access to <code>cwd</code> in
<code>createOnce</code> in ESLint interop mode (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15488">#15488</a>)
(overlookmotel)</li>
<li>732205e parser: Reject <code>using</code> / <code>await using</code>
in a switch <code>case</code> / <code>default</code> clause (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15225">#15225</a>)
(sapphi-red)</li>
<li>a17ca32 linter/plugins: Replace <code>Context</code> class (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15448">#15448</a>)
(overlookmotel)</li>
<li>ecf2f7b language_server: Fail gracefully when tsgolint executable
not found (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15436">#15436</a>)
(camc314)</li>
<li>3c8d3a7 lang-server: Improve logging in failure case for tsgolint
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15299">#15299</a>)
(camc314)</li>
<li>ef71410 linter: Use jsx if source type is JS in fix debug assertion
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15434">#15434</a>)
(camc314)</li>
<li>e32bbf6 linter/no-var: Handle TypeScript declare keyword in fixer
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15426">#15426</a>)
(camc314)</li>
<li>6565dbe linter/switch-case-braces: Skip comments when searching for
<code>:</code> token (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15425">#15425</a>)
(camc314)</li>
<li>85bd19a linter/prefer-class-fields: Insert value after type
annotation in fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15423">#15423</a>)
(camc314)</li>
<li>fde753e linter/plugins: Block access to
<code>context.settings</code> in <code>createOnce</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15394">#15394</a>)
(overlookmotel)</li>
<li>ddd9f9f linter/forward-ref-uses-ref: Dont suggest removing wrapper
in invalid positions (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15388">#15388</a>)
(camc314)</li>
<li>dac2a9c linter/no-template-curly-in-string: Remove fixer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15387">#15387</a>)
(camc314)</li>
<li>989b8e3 linter/no-var: Only fix to <code>const</code> if the var has
an initializer (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15385">#15385</a>)
(camc314)</li>
<li>cc403f5 linter/plugins: Return empty object for unimplemented
parserServices (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15364">#15364</a>)
(magic-akari)</li>
</ul>
<h3>⚡ Performance</h3>
<ul>
<li>25d577e language_server: Start tools in parallel (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15500">#15500</a>)
(Sysix)</li>
<li>3c57291 linter/plugins: Optimize loops (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15449">#15449</a>)
(overlookmotel)</li>
<li>3166233 linter/plugins: Remove <code>Arc</code>s (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15431">#15431</a>)
(overlookmotel)</li>
<li>9de1322 linter/plugins: Lazily deserialize settings JSON (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15395">#15395</a>)
(overlookmotel)</li>
<li>3049ec2 linter/plugins: Optimize <code>deepFreezeSettings</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15392">#15392</a>)
(overlookmotel)</li>
<li>444ebfd linter/plugins: Use single object for
<code>parserServices</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15378">#15378</a>)
(overlookmotel)</li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>97d2104 linter: Update comment in lint.rs about default value for
tsconfig path (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15530">#15530</a>)
(Connor Shea)</li>
<li>2c6bd9e linter: Always refer as &quot;ES2015&quot; instead of
&quot;ES6&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15411">#15411</a>)
(sapphi-red)</li>
<li>a0c5203 linter/import/named: Update &quot;ES7&quot; comment in
examples (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15410">#15410</a>)
(sapphi-red)</li>
<li>3dc24b5 linter,minifier: Always refer as &quot;ES Modules&quot;
instead of &quot;ES6 Modules&quot; (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15409">#15409</a>)
(sapphi-red)</li>
<li>2ad77fb linter/no-this-before-super: Correct &quot;Why is this
bad?&quot; section (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15408">#15408</a>)
(sapphi-red)</li>
<li>57f0ce1 linter: Add backquotes where appropriate (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/15407">#15407</a>)
(sapphi-red)</li>
</ul>
<h1>Oxfmt v0.12.0</h1>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md">oxlint's
changelog</a>.</em></p>
<blockquote>
<h2>[1.68.0] - 2026-06-01</h2>
<h3>🚀 Features</h3>
<ul>
<li>e4b1f46 linter/typescript: Implement
<code>method-signature-style</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22679">#22679</a>)
(Mikhail Baev)</li>
<li>bc462ca linter/vue: Implement no-reserved-component-names rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22741">#22741</a>)
(bab)</li>
<li>ef9e751 linter/vue: Implement component-definition-name-casing rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22818">#22818</a>)
(bab)</li>
<li>d67f51a linter/vue: Implement require-prop-type-constructor rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22708">#22708</a>)
(bab)</li>
<li>8422e8b linter/jsdoc: Implement
<code>require-yields-description</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22805">#22805</a>)
(Mikhail Baev)</li>
<li>fe93f97 linter/eslint: Implement
<code>prefer-named-capture-group</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22759">#22759</a>)
(Sebastian Poxhofer)</li>
</ul>
<h2>[1.67.0] - 2026-05-26</h2>
<h3>🚀 Features</h3>
<ul>
<li>b84941e linter/vue: Implement no-expose-after-await rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22675">#22675</a>)
(bab)</li>
<li>98b98c1 linter/vue: Implement no-computed-properties-in-data rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22674">#22674</a>)
(bab)</li>
<li>2d4c919 oxlint: Support <code>vite-plus/resolveConfig</code> for
vite.config.ts (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22456">#22456</a>)
(leaysgur)</li>
<li>2a60012 linter/vue: Implement require-render-return rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22613">#22613</a>)
(bab)</li>
<li>9f227fd linter/vue: Implement no-deprecated-props-default-this rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/21892">#21892</a>)
(bab)</li>
<li>87f065e linter/vue: Implement return-in-emits-validator rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/21935">#21935</a>)
(bab)</li>
<li>ea0380c linter/unicorn: Implement <code>import-style</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22173">#22173</a>)
(Hao Chen)</li>
<li>dde40fe linter/vue: Implement no-watch-after-await rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22006">#22006</a>)
(bab)</li>
<li>a735eb0 linter/vue: Implement valid-next-tick rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22531">#22531</a>)
(bab)</li>
<li>6dc615d linter/vue: Implement no-shared-component-data rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/21842">#21842</a>)
(bab)</li>
<li>a656418 linter/vue: Implement valid-define-options rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22107">#22107</a>)
(bab)</li>
<li>bb6f1b2 linter/vue: Implement require-slots-as-functions rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22244">#22244</a>)
(bab)</li>
<li>5fa4774 linter/n: Implement <code>callback-return</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22470">#22470</a>)
(Mikhail Baev)</li>
</ul>
<h2>[1.66.0] - 2026-05-18</h2>
<h3>🚀 Features</h3>
<ul>
<li>0440b0f linter/eslint: Implement <code>id-match</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22379">#22379</a>)
(Vladislav Sayapin)</li>
<li>65bf119 linter: Implement react no-object-type-as-default-prop (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22481">#22481</a>)
(uhyo)</li>
<li>2a6ddce linter/eslint: Implement <code>no-implied-eval</code> rule
(<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22391">#22391</a>)
(Vladislav Sayapin)</li>
<li>625758a linter/vitest: Implement padding-around-after-all-blocks
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/21788">#21788</a>)
(kapobajza)</li>
<li>37680b0 linter: Implement react no-unstable-nested-components (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22248">#22248</a>)
(Jovi De Croock)</li>
<li>d8d9c74 linter: Implement import/newline-after-import rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/19142">#19142</a>)
(Ryuya Yanagi)</li>
</ul>
<h2>[1.65.0] - 2026-05-15</h2>
<h3>🚀 Features</h3>
<ul>
<li>5478fb5 linter/jsdoc: Implement
<code>require-throws-description</code> rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22386">#22386</a>)
(Mikhail Baev)</li>
<li>c73225e linter/eslint: Implement <code>prefer-arrow-callback</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22312">#22312</a>)
(박천(Cheon Park))</li>
<li>de82b59 linter: Add support for
<code>eslint-plugin-jsx-a11y-x</code> (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22356">#22356</a>)
(mehm8128)</li>
<li>f44b6c8 linter: Fill schemas <code>DummyRuleMap</code> with built-in
rules (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22288">#22288</a>)
(Sysix)</li>
</ul>
<h2>[1.64.0] - 2026-05-11</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/oxc/commit/964a7580840f394d67c149ea083e35a1e74c128f"><code>964a758</code></a>
release(apps): oxlint v1.68.0 &amp;&amp; oxfmt v0.53.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22883">#22883</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/3f05c5e1267c25daa1c90babd84427f59acf96be"><code>3f05c5e</code></a>
feat(linter): expose <code>override::exclude_files</code> option (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22884">#22884</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/e4b1f46bec95da661af72f513e769d729ff605c6"><code>e4b1f46</code></a>
feat(linter/typescript): implement <code>method-signature-style</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22679">#22679</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/bc462ca5a778c246d6185d9b8d2cbdf3919ed527"><code>bc462ca</code></a>
feat(linter/vue): implement no-reserved-component-names rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22741">#22741</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/ef9e75170dca39091e4aa8360f7d59dc5aa206eb"><code>ef9e751</code></a>
feat(linter/vue): implement component-definition-name-casing rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22818">#22818</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/d67f51aba16939ce33b21c7504e177a9ff1c6887"><code>d67f51a</code></a>
feat(linter/vue): implement require-prop-type-constructor rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22708">#22708</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/8422e8bc44db47033ce516f9375867624e265823"><code>8422e8b</code></a>
feat(linter/jsdoc): implement <code>require-yields-description</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22805">#22805</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/fe93f9718ac09bab79286eb6dbc90ad14f8270bd"><code>fe93f97</code></a>
feat(linter/eslint): implement <code>prefer-named-capture-group</code>
rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22759">#22759</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/68b455d84f0b18bd6646cfe4f9babb12ec4fc448"><code>68b455d</code></a>
release(apps): oxlint v1.67.0 &amp;&amp; oxfmt v0.52.0 (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22735">#22735</a>)</li>
<li><a
href="https://github.com/oxc-project/oxc/commit/b84941e69e2e630e998fe6b1e90b0506608f7caa"><code>b84941e</code></a>
feat(linter/vue): implement no-expose-after-await rule (<a
href="https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint/issues/22675">#22675</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/oxc/commits/oxlint_v1.68.0/npm/oxlint">compare
view</a></li>
</ul>
</details>
<br />

Updates `oxlint-tsgolint` from 0.22.1 to 0.23.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/oxc-project/tsgolint/releases">oxlint-tsgolint's
releases</a>.</em></p>
<blockquote>
<h2>v0.23.0</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): update crate-ci/typos action to v1.45.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/915">oxc-project/tsgolint#915</a></li>
<li>feat: add skill for upgrading typescript-go by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/918">oxc-project/tsgolint#918</a></li>
<li>chore(deps): update pnpm to v10.33.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/921">oxc-project/tsgolint#921</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/922">oxc-project/tsgolint#922</a></li>
<li>fix: attach tsconfig path to diagnostics by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/923">oxc-project/tsgolint#923</a></li>
<li>fix(prefer-nullish-coalescing): parenthesize mixed logical fixes by
<a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/924">oxc-project/tsgolint#924</a></li>
<li>tests(return-await): cover non-async arrow functions by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/926">oxc-project/tsgolint#926</a></li>
<li>chore(deps): update github.com/go-json-experiment/json digest to
b6187a3 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/927">oxc-project/tsgolint#927</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/928">oxc-project/tsgolint#928</a></li>
<li>chore(deps): update crate-ci/typos action to v1.46.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/929">oxc-project/tsgolint#929</a></li>
<li>chore(deps): update module github.com/dlclark/regexp2 to v2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/930">oxc-project/tsgolint#930</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/931">oxc-project/tsgolint#931</a></li>
<li>chore(deps): update typescript-go digest to 48e2953 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/933">oxc-project/tsgolint#933</a></li>
<li>chore(deps): update typescript-go digest to 5eb880f by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/936">oxc-project/tsgolint#936</a></li>
<li>fix(no-misused-promises): handle empty JSX attributes by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/938">oxc-project/tsgolint#938</a></li>
<li>fix(no-unsafe-enum-comparison): flag string literal unions by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/937">oxc-project/tsgolint#937</a></li>
<li>chore(deps): update typescript-go digest to e1f8f97 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/939">oxc-project/tsgolint#939</a></li>
<li>chore(deps): update typescript-go digest to 092b34f by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/940">oxc-project/tsgolint#940</a></li>
<li>chore: configure typescript-go renovate schedule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/941">oxc-project/tsgolint#941</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/945">oxc-project/tsgolint#945</a></li>
<li>chore(deps): update dependency dprint-typescript to v0.96.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/947">oxc-project/tsgolint#947</a></li>
<li>chore(deps): update gomod by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/946">oxc-project/tsgolint#946</a></li>
<li>chore(deps): update crate-ci/typos action to v1.46.1 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/948">oxc-project/tsgolint#948</a></li>
<li>fix(prefer-nullish-coalescing): emit suggestion over fix by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/951">oxc-project/tsgolint#951</a></li>
<li>chore: update packageManager to pnpm 11.0.4 by <a
href="https://github.com/Boshen"><code>@​Boshen</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/953">oxc-project/tsgolint#953</a></li>
<li>chore: update typescript-go submodule by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/955">oxc-project/tsgolint#955</a></li>
<li>fix(no-nullable-type-assertion-style): use suggestion instead of fix
by <a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/956">oxc-project/tsgolint#956</a></li>
<li>docs: Update Go version requirement to 1.26 in CONTRIBUTING.md. by
<a href="https://github.com/connorshea"><code>@​connorshea</code></a> in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/957">oxc-project/tsgolint#957</a></li>
<li>fix: allow safe promise intersection members by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/959">oxc-project/tsgolint#959</a></li>
<li>ci: switch security workflow to ubuntu-latest by <a
href="https://github.com/Boshen"><code>@​Boshen</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/962">oxc-project/tsgolint#962</a></li>
<li>chore(deps): update dependency vitest to v4.1.6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/963">oxc-project/tsgolint#963</a></li>
<li>chore(deps): update module github.com/dlclark/regexp2/v2 to v2.0.3
by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/964">oxc-project/tsgolint#964</a></li>
<li>chore(deps): update dependency dprint-markdown to v0.22.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/965">oxc-project/tsgolint#965</a></li>
<li>chore(deps): update github actions by <a
href="https://github.com/renovate"><code>@​renovate</code></a>[bot] in
<a
href="https://redirect.github.com/oxc-project/tsgolint/pull/966">oxc-project/tsgolint#966</a></li>
<li>perf(no-unnecessary-type-parameters): stop counting settled
candidates by <a
href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/967">oxc-project/tsgolint#967</a></li>
<li>chore: add <code>dprint</code> to pnpm <code>allowBuilds</code> by
<a href="https://github.com/camc314"><code>@​camc314</code></a> in <a
href="https://redirect.github.com/oxc-project/tsgolint/pull/968">oxc-project/tsgolint#968</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/oxc-project/tsgolint/compare/v0.22.1...v0.23.0">https://github.com/oxc-project/tsgolint/compare/v0.22.1...v0.23.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/0e575fae8407227601f66c1d8d8927a535aea58b"><code>0e575fa</code></a>
chore: add <code>dprint</code> to pnpm <code>allowBuilds</code> (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/968">#968</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/bb8886bef7ae76cf3280852228a05214c54f2a83"><code>bb8886b</code></a>
perf(no-unnecessary-type-parameters): stop counting settled candidates
(<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/967">#967</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/90be7b2609efd2bcae290b09e4835fe9ae52c63e"><code>90be7b2</code></a>
chore(deps): update github actions (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/966">#966</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/cdae358c525a9a93ab48af36b51ae2a6c740830d"><code>cdae358</code></a>
chore(deps): update dependency dprint-markdown to v0.22.0 (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/965">#965</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/d356c9e3d66d0b4fbe1b7353fcf5b8f857d6ed80"><code>d356c9e</code></a>
chore(deps): update module github.com/dlclark/regexp2/v2 to v2.0.3 (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/964">#964</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/7cba6be4c0d972578d14e52c7a454a0a15961727"><code>7cba6be</code></a>
chore(deps): update dependency vitest to v4.1.6 (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/963">#963</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/1dcd2a6f4138f4b9a273a231def838995ac589e5"><code>1dcd2a6</code></a>
ci: switch security workflow to ubuntu-latest (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/962">#962</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/b4f66246a62ea03d7cd664bf940d2f978c2068d5"><code>b4f6624</code></a>
fix: allow safe promise intersection members (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/959">#959</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/233eeb35db9d698db67c4d4247963047ceb30fb7"><code>233eeb3</code></a>
docs: Update Go version requirement to 1.26 in CONTRIBUTING.md. (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/957">#957</a>)</li>
<li><a
href="https://github.com/oxc-project/tsgolint/commit/8bd37abc596e5dd0d54ec6625b6c2a77922b7ca4"><code>8bd37ab</code></a>
fix(no-nullable-type-assertion-style): use suggestion instead of fix (<a
href="https://redirect.github.com/oxc-project/tsgolint/issues/956">#956</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/oxc-project/tsgolint/compare/v0.22.1...v0.23.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `tailwindcss` from 4.2.4 to 4.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases">tailwindcss's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<h3>Added</h3>
<ul>
<li>Add <code>@container-size</code> utility (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18901">#18901</a>)</li>
<li>Add <code>scrollbar-{auto,thin,none}</code> utilities for
<code>scrollbar-width</code>, and <code>scrollbar-thumb-*</code> /
<code>scrollbar-track-*</code> color utilities for
<code>scrollbar-color</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19981">#19981</a>,
<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20019">#20019</a>)</li>
<li>Add <code>scrollbar-gutter-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20018">#20018</a>)</li>
<li>Add <code>zoom-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20020">#20020</a>)</li>
<li>Add <code>tab-*</code> utilities (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/20022">#20022</a>)</li>
<li>Allow using <code>@variant</code> with stacked variants (e.g.
<code>@variant hover:focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Allow using <code>@variant</code> with compound variants (e.g.
<code>@variant hover, focus { … }</code>) (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19996">#19996</a>)</li>
<li>Support <code>--default(…)</code> in <code>--value(…)</code> and
<code>--modifier(…)</code> for functional <code>@utility</code>
definitions (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19989">#19989</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure <code>@plugin</code> resolves package JavaScript entries
instead of browser CSS entries when using <code>@tailwindcss/vite</code>
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19949">#19949</a>)</li>
<li>Fix relative <code>@import</code> and <code>@plugin</code> paths
resolving from the wrong directory when using
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19965">#19965</a>)</li>
<li>Ensure CSS files containing <code>@variant</code> are processed by
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19966">#19966</a>)</li>
<li>Resolve imports relative to <code>base</code> when
<code>result.opts.from</code> is not provided when using
<code>@tailwindcss/postcss</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19980">#19980</a>)</li>
<li>Canonicalization: preserve significant <code>_</code> whitespace in
arbitrary values (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19986">#19986</a>)</li>
<li>Canonicalization: add parentheses when removing whitespace from
arbitrary values would hurt readability (e.g.
<code>w-[calc(100%---spacing...

_Description has been truncated_

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-09 20:53:10 -04:00
dependabot[bot]andCaliBrain 2e25d2d8db Bump qbittorrent-api from 2025.11.1 to 2026.5.1 (#991)
Bumps [qbittorrent-api](https://github.com/rmartin16/qbittorrent-api)
from 2025.11.1 to 2026.5.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/releases">qbittorrent-api's
releases</a>.</em></p>
<blockquote>
<h2>release-2026.5.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Add missing tracker statuses by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/613">rmartin16/qbittorrent-api#613</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.0...v2026.5.1">https://github.com/rmartin16/qbittorrent-api/compare/v2026.5.0...v2026.5.1</a></p>
<h2>release-2026.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add v5_1_x to QBT_VER matrix in CI workflow by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/580">rmartin16/qbittorrent-api#580</a></li>
<li>typo-- by <a
href="https://github.com/ratijas"><code>@​ratijas</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/591">rmartin16/qbittorrent-api#591</a></li>
<li>Update to latest qBittorrent wiki links by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/592">rmartin16/qbittorrent-api#592</a></li>
<li>Disable problematic http scheme change test by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/593">rmartin16/qbittorrent-api#593</a></li>
<li>limit chardet version by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/595">rmartin16/qbittorrent-api#595</a></li>
<li>skip <code>test_update_plugins</code> test for older qbittorrent
versions by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/599">rmartin16/qbittorrent-api#599</a></li>
<li>Add v5_2_x to test matrix by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/601">rmartin16/qbittorrent-api#601</a></li>
<li>fix test failing for unverified request against master by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/600">rmartin16/qbittorrent-api#600</a></li>
<li>Advertise support for qBittorrent v5.2.0 by <a
href="https://github.com/rmartin16"><code>@​rmartin16</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/611">rmartin16/qbittorrent-api#611</a></li>
<li>feat: add torrents_set_comment method to set comments for torrents
by <a href="https://github.com/trim21"><code>@​trim21</code></a> in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/610">rmartin16/qbittorrent-api#610</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/ratijas"><code>@​ratijas</code></a> made
their first contribution in <a
href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/591">rmartin16/qbittorrent-api#591</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2025.11.1...v2026.5.0">https://github.com/rmartin16/qbittorrent-api/compare/v2025.11.1...v2026.5.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md">qbittorrent-api's
changelog</a>.</em></p>
<blockquote>
<h3>v2026.5.1 (05 may 2026)</h3>
<ul>
<li>Add new tracker statuses for qBittorrent v5.2.0 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/613">#613</a>)</li>
</ul>
<h3>v2026.5.0 (03 may 2026)</h3>
<ul>
<li>Advertise support for qBittorrent v5.2.0</li>
<li>Add support for torrent setComment endpoints (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/610">#610</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/85b6e4d3da4146e40fcaefcd4fecb9186f33c1cb"><code>85b6e4d</code></a>
Bump to v2026.5.1</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/a1c13dd50ae8c8caeac9bb4806830ef62edbbb94"><code>a1c13dd</code></a>
Add missing tracker statuses (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/613">#613</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/b6c7cdcdc88ebf1be0267fe0308e5b7aba551152"><code>b6c7cdc</code></a>
feat: add torrents_set_comment method to set comments for torrents (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/610">#610</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/46b3a5dc06fb409a83edcec7877961b2331610cb"><code>46b3a5d</code></a>
Advertise support for qBittorrent v5.2.0 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/611">#611</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/f0f96970b6506b8411460d0ae991c56918325922"><code>f0f9697</code></a>
Bumped pre-commit hook for mirrors-mypy from v1.20.0 to v1.20.2 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/608">#608</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/e2bf3dde05ad8280faf9d489350646434a3d4dd0"><code>e2bf3dd</code></a>
Bumped pre-commit hook for ruff-pre-commit from v0.15.8 to v0.15.12 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/609">#609</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/19df4c7f45354935b84987f5df8d7f789784b92f"><code>19df4c7</code></a>
Bump build from 1.4.2 to 1.4.4 in the pip group (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/607">#607</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/10fc622202ae819c36856c728e25d9d54e44923d"><code>10fc622</code></a>
Bump the github-actions group with 4 updates (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/606">#606</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/33f5e1c1d731bb042e7f3a6d5accb1138f8cef97"><code>33f5e1c</code></a>
Bump the github-actions group with 6 updates (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/602">#602</a>)</li>
<li><a
href="https://github.com/rmartin16/qbittorrent-api/commit/31f90f35166ade72495fffae268f657e78a52818"><code>31f90f3</code></a>
Bumped pre-commit hook for ruff-pre-commit from v0.15.4 to v0.15.8 (<a
href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/604">#604</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/rmartin16/qbittorrent-api/compare/v2025.11.1...v2026.5.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=qbittorrent-api&package-manager=uv&previous-version=2025.11.1&new-version=2026.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-09 20:51:26 -04:00
dependabot[bot]andCaliBrain 709d3828d9 Bump the docker-base-image-digests group across 1 directory with 2 updates (#1015)
Bumps the docker-base-image-digests group with 2 updates in the /
directory: node and python.

Updates `node` from `d1b3b4d` to `2bdb65e`

Updates `python` from 3.14-slim to 3.14.5-slim


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: CaliBrain <calibrain@l4n.xyz>
2026-06-09 20:43:01 -04:00
dependabot[bot] d808c362ea Bump the gh-actions group across 1 directory with 6 updates (#1044)
Bumps the gh-actions group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `6.0.2` |
`6.0.3` |
| [docker/login-action](https://github.com/docker/login-action) |
`4.1.0` | `4.2.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) |
`6.0.0` | `6.1.0` |
|
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action)
| `4.0.0` | `4.1.0` |
|
[docker/build-push-action](https://github.com/docker/build-push-action)
| `7.1.0` | `7.2.0` |
| [github/codeql-action](https://github.com/github/codeql-action) |
`4.35.4` | `4.36.1` |


Updates `actions/checkout` from 6.0.2 to 6.0.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update changelog by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2357">actions/checkout#2357</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>Update changelog for v6.0.3 by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2446">actions/checkout#2446</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yaananth"><code>@​yaananth</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.3">https://github.com/actions/checkout/compare/v6...v6.0.3</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>v6.0.3</h2>
<ul>
<li>Fix checkout init for SHA-256 repositories by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li>
<li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a
href="https://github.com/yaananth"><code>@​yaananth</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li>
</ul>
<h2>v6.0.2</h2>
<ul>
<li>Fix tag handling: preserve annotations and explicit fetch-tags by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li>
</ul>
<h2>v6.0.1</h2>
<ul>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
</ul>
<h2>v6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>v5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>v5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>v4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>v4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/checkout/commit/df4cb1c069e1874edd31b4311f1884172cec0e10"><code>df4cb1c</code></a>
Update changelog for v6.0.3 (<a
href="https://redirect.github.com/actions/checkout/issues/2446">#2446</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/1cce3390c2bfda521930d01229c073c7ff920824"><code>1cce339</code></a>
Fix checkout init for SHA-256 repositories (<a
href="https://redirect.github.com/actions/checkout/issues/2439">#2439</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/900f2210b1d28bbbd0bd22d17926b9e224e8f231"><code>900f221</code></a>
fix: expand merge commit SHA regex and add SHA-256 test cases (<a
href="https://redirect.github.com/actions/checkout/issues/2414">#2414</a>)</li>
<li><a
href="https://github.com/actions/checkout/commit/0c366fd6a839edf440554fa01a7085ccba70ac98"><code>0c366fd</code></a>
Update changelog (<a
href="https://redirect.github.com/actions/checkout/issues/2357">#2357</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/login-action` from 4.1.0 to 4.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/login-action/releases">docker/login-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.0</h2>
<ul>
<li>Bump <code>@​actions/core</code> from 3.0.0 to 3.0.1 in <a
href="https://redirect.github.com/docker/login-action/pull/976">docker/login-action#976</a></li>
<li>Bump <code>@​aws-sdk/client-ecr</code> and
<code>@​aws-sdk/client-ecr-public</code> to 3.1050.0 in <a
href="https://redirect.github.com/docker/login-action/pull/960">docker/login-action#960</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.86.0 to 0.90.0 in
<a
href="https://redirect.github.com/docker/login-action/pull/970">docker/login-action#970</a></li>
<li>Bump brace-expansion from 2.0.1 to 5.0.6 in <a
href="https://redirect.github.com/docker/login-action/pull/993">docker/login-action#993</a></li>
<li>Bump fast-xml-builder from 1.1.4 to 1.2.0 in <a
href="https://redirect.github.com/docker/login-action/pull/985">docker/login-action#985</a></li>
<li>Bump fast-xml-parser from 5.3.6 to 5.8.0 in <a
href="https://redirect.github.com/docker/login-action/pull/963">docker/login-action#963</a></li>
<li>Bump http-proxy-agent and https-proxy-agent to 9.0.0 in <a
href="https://redirect.github.com/docker/login-action/pull/961">docker/login-action#961</a></li>
<li>Bump postcss from 8.5.6 to 8.5.10 in <a
href="https://redirect.github.com/docker/login-action/pull/979">docker/login-action#979</a></li>
<li>Bump tar from 6.2.1 to 7.5.15 in <a
href="https://redirect.github.com/docker/login-action/pull/991">docker/login-action#991</a></li>
<li>Bump vite from 7.3.1 to 7.3.3 in <a
href="https://redirect.github.com/docker/login-action/pull/986">docker/login-action#986</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/login-action/compare/v4.1.0...v4.2.0">https://github.com/docker/login-action/compare/v4.1.0...v4.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/login-action/commit/650006c6eb7dba73a995cc03b0b2d7f5ca915bee"><code>650006c</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/960">#960</a>
from docker/dependabot/npm_and_yarn/aws-sdk-dependenc...</li>
<li><a
href="https://github.com/docker/login-action/commit/99df1a3f6d65e48177ea57671a50e2242eae4b63"><code>99df1a3</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/3ab375f324f46da5f6901efeda4be4e2566ebaa2"><code>3ab375f</code></a>
build(deps): bump the aws-sdk-dependencies group across 1 directory with
2 up...</li>
<li><a
href="https://github.com/docker/login-action/commit/39d85804ae465a1816c68ff58158ec66883981b4"><code>39d8580</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/970">#970</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/login-action/commit/4eefcd33ca7213989697445a78b6730274bfaba6"><code>4eefcd3</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/56d092c8b3f04006c22f4fc20a2b3d2442caed56"><code>56d092c</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.86.0 to
0.90.0</li>
<li><a
href="https://github.com/docker/login-action/commit/e2e31ca87063ae00fd41ad3b9c548dd8ec24c5ff"><code>e2e31ca</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/976">#976</a>
from docker/dependabot/npm_and_yarn/actions/core-3.0.1</li>
<li><a
href="https://github.com/docker/login-action/commit/0bced941e843afc786fbfd58b1c6c13ca11e09c9"><code>0bced94</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/3e75a0f266b07e09777a621d0ca5f4432ef9f10c"><code>3e75a0f</code></a>
build(deps): bump <code>@​actions/core</code> from 3.0.0 to 3.0.1</li>
<li><a
href="https://github.com/docker/login-action/commit/365bebd9d646160567ebad47824f026e09ee6970"><code>365bebd</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/984">#984</a>
from docker/dependabot/github_actions/aws-actions/con...</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/login-action/compare/4907a6ddec9925e35a0a9e82d7399ccc52663121...650006c6eb7dba73a995cc03b0b2d7f5ca915bee">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/metadata-action` from 6.0.0 to 6.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/metadata-action/releases">docker/metadata-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.79.0 to 0.90.0 in
<a
href="https://redirect.github.com/docker/metadata-action/pull/613">docker/metadata-action#613</a></li>
<li>Bump brace-expansion from 1.1.12 to 5.0.6 in <a
href="https://redirect.github.com/docker/metadata-action/pull/658">docker/metadata-action#658</a>
<a
href="https://redirect.github.com/docker/metadata-action/pull/630">docker/metadata-action#630</a></li>
<li>Bump csv-parse from 6.1.0 to 6.2.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/617">docker/metadata-action#617</a></li>
<li>Bump fast-xml-parser from 5.4.2 to 5.8.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/620">docker/metadata-action#620</a></li>
<li>Bump flatted from 3.3.3 to 3.4.2 in <a
href="https://redirect.github.com/docker/metadata-action/pull/623">docker/metadata-action#623</a></li>
<li>Bump glob from 10.3.15 to 10.5.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/621">docker/metadata-action#621</a></li>
<li>Bump handlebars from 4.7.8 to 4.7.9 in <a
href="https://redirect.github.com/docker/metadata-action/pull/629">docker/metadata-action#629</a></li>
<li>Bump lodash from 4.17.23 to 4.18.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/639">docker/metadata-action#639</a></li>
<li>Bump moment-timezone from 0.6.0 to 0.6.1 in <a
href="https://redirect.github.com/docker/metadata-action/pull/619">docker/metadata-action#619</a></li>
<li>Bump picomatch from 4.0.3 to 4.0.4 in <a
href="https://redirect.github.com/docker/metadata-action/pull/626">docker/metadata-action#626</a></li>
<li>Bump postcss from 8.5.6 to 8.5.10 in <a
href="https://redirect.github.com/docker/metadata-action/pull/649">docker/metadata-action#649</a></li>
<li>Bump tar from 6.2.1 to 7.5.15 in <a
href="https://redirect.github.com/docker/metadata-action/pull/657">docker/metadata-action#657</a></li>
<li>Bump undici from 6.23.0 to 6.25.0 in <a
href="https://redirect.github.com/docker/metadata-action/pull/614">docker/metadata-action#614</a></li>
<li>Bump vite from 7.3.1 to 7.3.2 in <a
href="https://redirect.github.com/docker/metadata-action/pull/637">docker/metadata-action#637</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/metadata-action/compare/v6.0.0...v6.1.0">https://github.com/docker/metadata-action/compare/v6.0.0...v6.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/metadata-action/commit/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9"><code>80c7e94</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/613">#613</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/metadata-action/commit/8e0ddab90c29de6fff30c787e328563e48106fd0"><code>8e0ddab</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/metadata-action/commit/a8db14bd863c93be08c93c13e1cc816ec5b49b2e"><code>a8db14b</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.79.0 to
0.90.0</li>
<li><a
href="https://github.com/docker/metadata-action/commit/63a7371ee01888324f2c7b3e18be9ac13b9dbdbc"><code>63a7371</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/617">#617</a>
from docker/dependabot/npm_and_yarn/csv-parse-6.2.0</li>
<li><a
href="https://github.com/docker/metadata-action/commit/c6916a6cf86608c44ba936565d57f550835ecd45"><code>c6916a6</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/metadata-action/commit/aca9205632182712a2d859059cf12fdc9b2ca202"><code>aca9205</code></a>
chore(deps): Bump csv-parse from 6.1.0 to 6.2.1</li>
<li><a
href="https://github.com/docker/metadata-action/commit/9dcfe60f10ebea72e9e48bf8bf366d01629d045a"><code>9dcfe60</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/629">#629</a>
from docker/dependabot/npm_and_yarn/handlebars-4.7.9</li>
<li><a
href="https://github.com/docker/metadata-action/commit/43dea7677c80686dc31a7b16e61ba9d542081b59"><code>43dea76</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/metadata-action/commit/7a56f5af0aa2d36278ba725bb44091417def9f73"><code>7a56f5a</code></a>
chore(deps): Bump handlebars from 4.7.8 to 4.7.9</li>
<li><a
href="https://github.com/docker/metadata-action/commit/e49e0aa5deac3d581afd6ce80464d84ef68f5ccc"><code>e49e0aa</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/metadata-action/issues/658">#658</a>
from docker/dependabot/npm_and_yarn/brace-expansion-5...</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/metadata-action/compare/030e881283bb7a6894de51c315a6bfe6a94e05cf...80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/setup-buildx-action` from 4.0.0 to 4.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.79.0 to 0.90.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/489">docker/setup-buildx-action#489</a></li>
<li>Bump brace-expansion from 1.1.12 to 5.0.6 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/547">docker/setup-buildx-action#547</a>
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/508">docker/setup-buildx-action#508</a></li>
<li>Bump fast-xml-builder from 1.0.0 to 1.2.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/540">docker/setup-buildx-action#540</a></li>
<li>Bump fast-xml-parser from 5.4.2 to 5.8.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/496">docker/setup-buildx-action#496</a></li>
<li>Bump flatted from 3.3.3 to 3.4.2 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/499">docker/setup-buildx-action#499</a></li>
<li>Bump glob from 10.3.12 to 13.0.6 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/495">docker/setup-buildx-action#495</a></li>
<li>Bump handlebars from 4.7.8 to 4.7.9 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/504">docker/setup-buildx-action#504</a></li>
<li>Bump lodash from 4.17.23 to 4.18.1 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/523">docker/setup-buildx-action#523</a></li>
<li>Bump picomatch from 4.0.3 to 4.0.4 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/503">docker/setup-buildx-action#503</a></li>
<li>Bump postcss from 8.5.6 to 8.5.10 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/537">docker/setup-buildx-action#537</a></li>
<li>Bump tar from 6.2.1 to 7.5.15 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/545">docker/setup-buildx-action#545</a></li>
<li>Bump undici from 6.23.0 to 6.25.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/492">docker/setup-buildx-action#492</a></li>
<li>Bump vite from 7.3.1 to 7.3.2 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/520">docker/setup-buildx-action#520</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v4.0.0...v4.1.0">https://github.com/docker/setup-buildx-action/compare/v4.0.0...v4.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5"><code>d7f5e7f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/489">#489</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/92bc5c9777806d0a73d9d668ba2114fa1177f164"><code>92bc5c9</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/da11e35abee0f20cb4f1c1b7c461d37c29be52f5"><code>da11e35</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.79.0 to
0.90.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/f021e162ef95b6fba51af1c6674f537f25bce851"><code>f021e16</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/492">#492</a>
from docker/dependabot/npm_and_yarn/undici-6.24.1</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/b5af94fab700aee0c64d6077e0e34ae987815b67"><code>b5af94f</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/16ad9776a801d0c47f0a05f007b88a3789aa8ab6"><code>16ad977</code></a>
build(deps): bump undici from 6.23.0 to 6.25.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/d7a12d7df895b33bd02a9b4bf62a12f2b9a24458"><code>d7a12d7</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/495">#495</a>
from docker/dependabot/npm_and_yarn/glob-10.5.0</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/28ff27de4eed7518d361591f2cd1dfb69c34a7cb"><code>28ff27d</code></a>
build(deps): bump glob from 10.3.12 to 13.0.6</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/daf436b50e13d9053b9730cbc16516891878b019"><code>daf436b</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/496">#496</a>
from docker/dependabot/npm_and_yarn/fast-xml-parser-5...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/9725348367859764880f2f2e688a6b0c353e3f35"><code>9725348</code></a>
chore: update generated content</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-buildx-action/compare/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd...d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/build-push-action` from 7.1.0 to 7.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.0</h2>
<ul>
<li>Bump <code>@​actions/core</code> from 3.0.0 to 3.0.1 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1525">docker/build-push-action#1525</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.87.0 to 0.90.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1517">docker/build-push-action#1517</a></li>
<li>Bump brace-expansion from 2.0.2 to 5.0.6 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1534">docker/build-push-action#1534</a></li>
<li>Bump fast-xml-builder from 1.1.4 to 1.2.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1529">docker/build-push-action#1529</a></li>
<li>Bump fast-xml-parser from 5.5.7 to 5.8.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1521">docker/build-push-action#1521</a></li>
<li>Bump postcss from 8.5.6 to 8.5.10 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1526">docker/build-push-action#1526</a></li>
<li>Bump tar from 6.2.1 to 7.5.15 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1533">docker/build-push-action#1533</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v7.1.0...v7.2.0">https://github.com/docker/build-push-action/compare/v7.1.0...v7.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/build-push-action/commit/f9f3042f7e2789586610d6e8b85c8f03e5195baf"><code>f9f3042</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1517">#1517</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/812d5fd9212a4c5d419e5be02fd8e9bb435c5d76"><code>812d5fd</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/b6f66930769f2917a3275dc4d81f15583ac7e105"><code>b6f6693</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.87.0 to
0.90.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/c1c626eced73a500ec65c4256c620b3b9e8278c0"><code>c1c626e</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1525">#1525</a>
from docker/dependabot/npm_and_yarn/actions/core-3.0.1</li>
<li><a
href="https://github.com/docker/build-push-action/commit/51bb284cd4d05650aa6f5e4e22cb96d2cbfe62b7"><code>51bb284</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/5f7884def8f133e8ef40c53d003d1471c05621c6"><code>5f7884d</code></a>
chore(deps): Bump <code>@​actions/core</code> from 3.0.0 to 3.0.1</li>
<li><a
href="https://github.com/docker/build-push-action/commit/e01deff7d956c756a20f3e19ff7ddc0e4a50fc1d"><code>e01deff</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1521">#1521</a>
from docker/dependabot/npm_and_yarn/fast-xml-parser-...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/3804d497934b39bd591ee9d1c6c9e593b4488a67"><code>3804d49</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/71e8947aac5dad23ce83a43e9c98f750e02de2f3"><code>71e8947</code></a>
chore(deps): Bump fast-xml-parser from 5.5.7 to 5.8.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/4925ad24cdbc42ff492d76cf9fe7a30b79976b60"><code>4925ad2</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1526">#1526</a>
from docker/dependabot/npm_and_yarn/postcss-8.5.10</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/build-push-action/compare/bcafcacb16a39f128d818304e6c9c0c18556b85f...f9f3042f7e2789586610d6e8b85c8f03e5195baf">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 4.35.4 to 4.36.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.36.1</h2>
<p>No user facing changes.</p>
<h2>v4.36.0</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>v4.35.5</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.36.2 - 04 Jun 2026</h2>
<ul>
<li>Cache CodeQL CLI version information across Actions steps. <a
href="https://redirect.github.com/github/codeql-action/pull/3943">#3943</a></li>
<li>Reduce requests while waiting for analysis processing by using
exponential backoff when polling SARIF processing status. <a
href="https://redirect.github.com/github/codeql-action/pull/3937">#3937</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6">2.25.6</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3948">#3948</a></li>
</ul>
<h2>4.36.1 - 02 Jun 2026</h2>
<p>No user facing changes.</p>
<h2>4.36.0 - 22 May 2026</h2>
<ul>
<li><em>Breaking change</em>: Bump the minimum required CodeQL bundle
version to 2.19.4. <a
href="https://redirect.github.com/github/codeql-action/pull/3894">#3894</a></li>
<li>Add support for SHA-256 Git object IDs. <a
href="https://redirect.github.com/github/codeql-action/pull/3893">#3893</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5">2.25.5</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3926">#3926</a></li>
</ul>
<h2>4.35.5 - 15 May 2026</h2>
<ul>
<li>We have improved how the JavaScript bundles for the CodeQL Action
are generated to avoid duplication across bundles and reduce the size of
the repository by around 70%. This should have no effect on the runtime
behaviour of the CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3899">#3899</a></li>
<li>For performance and accuracy reasons, <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> will now only be enabled on a pull request when
diff-informed analysis is also enabled for that run. If diff-informed
analysis is unavailable (for example, because the PR diff ranges could
not be computed), the action will fall back to a full analysis. <a
href="https://redirect.github.com/github/codeql-action/pull/3791">#3791</a></li>
<li>If multiple inputs are provided for the GitHub-internal
<code>analysis-kinds</code> input, only <code>code-scanning</code> will
be enabled. The <code>analysis-kinds</code> input is experimental, for
GitHub-internal use only, and may change without notice at any time. <a
href="https://redirect.github.com/github/codeql-action/pull/3892">#3892</a></li>
<li>Added an experimental change which, when running a Code Scanning
analysis for a PR with <a
href="https://redirect.github.com/github/roadmap/issues/1158">improved
incremental analysis</a> enabled, prefers CodeQL CLI versions that have
a cached overlay-base database for the configured languages. This speeds
up analysis for a repository when there is not yet a cached overlay-base
database for the latest CLI version. We expect to roll this change out
to everyone in May. <a
href="https://redirect.github.com/github/codeql-action/pull/3880">#3880</a></li>
</ul>
<h2>4.35.4 - 07 May 2026</h2>
<ul>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4">2.25.4</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3881">#3881</a></li>
</ul>
<h2>4.35.3 - 01 May 2026</h2>
<ul>
<li><em>Upcoming breaking change</em>: Add a deprecation warning for
customers using CodeQL version 2.19.3 and earlier. These versions of
CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise
Server 3.15, and will be unsupported by the next minor release of the
CodeQL Action. <a
href="https://redirect.github.com/github/codeql-action/pull/3837">#3837</a></li>
<li>Configurations for private registries that use Cloudsmith or GCP
OIDC are now accepted. <a
href="https://redirect.github.com/github/codeql-action/pull/3850">#3850</a></li>
<li>Best-effort connection tests for private registries now use
<code>GET</code> requests instead of <code>HEAD</code> for better
compatibility with various registry implementations. For NuGet feeds,
the test is now always performed against the service index. <a
href="https://redirect.github.com/github/codeql-action/pull/3853">#3853</a></li>
<li>Fixed a bug where two diagnostics produced within the same
millisecond could overwrite each other on disk, causing one of them to
be lost. <a
href="https://redirect.github.com/github/codeql-action/pull/3852">#3852</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3">2.25.3</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3865">#3865</a></li>
</ul>
<h2>4.35.2 - 15 Apr 2026</h2>
<ul>
<li>The undocumented TRAP cache cleanup feature that could be enabled
using the <code>CODEQL_ACTION_CLEANUP_TRAP_CACHES</code> environment
variable is deprecated and will be removed in May 2026. If you are
affected by this, we recommend disabling TRAP caching by passing the
<code>trap-caching: false</code> input to the <code>init</code> Action.
<a
href="https://redirect.github.com/github/codeql-action/pull/3795">#3795</a></li>
<li>The Git version 2.36.0 requirement for improved incremental analysis
now only applies to repositories that contain submodules. <a
href="https://redirect.github.com/github/codeql-action/pull/3789">#3789</a></li>
<li>Python analysis on GHES no longer extracts the standard library,
relying instead on models of the standard library. This should result in
significantly faster extraction and analysis times, while the effect on
alerts should be minimal. <a
href="https://redirect.github.com/github/codeql-action/pull/3794">#3794</a></li>
<li>Fixed a bug in the validation of OIDC configurations for private
registries that was added in CodeQL Action 4.33.0 / 3.33.0. <a
href="https://redirect.github.com/github/codeql-action/pull/3807">#3807</a></li>
<li>Update default CodeQL bundle version to <a
href="https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.2">2.25.2</a>.
<a
href="https://redirect.github.com/github/codeql-action/pull/3823">#3823</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/87557b9c84dde89fdd9b10e88954ac2f4248e463"><code>87557b9</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3940">#3940</a>
from github/update-v4.36.1-2a1689ed4</li>
<li><a
href="https://github.com/github/codeql-action/commit/94310119648b77e2153bf970fd244062806781de"><code>9431011</code></a>
Update changelog for v4.36.1</li>
<li><a
href="https://github.com/github/codeql-action/commit/2a1689ed43ccdf7eea07e03a75371ce6801d28e6"><code>2a1689e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3939">#3939</a>
from github/henrymercer/skip-overlay-revert-when-exp...</li>
<li><a
href="https://github.com/github/codeql-action/commit/524532393a46071bdfc81527a811ffa69e16723a"><code>5245323</code></a>
Disable missing diff-ranges fallback when overlay enabled manually</li>
<li><a
href="https://github.com/github/codeql-action/commit/d1eb1207b45130d2edf64a0aa1c93be23510592f"><code>d1eb120</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3933">#3933</a>
from github/update-supported-enterprise-server-versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/115001ba8d0198846992657731666b08686c8ded"><code>115001b</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3934">#3934</a>
from github/dependabot/npm_and_yarn/npm-minor-86fb5c...</li>
<li><a
href="https://github.com/github/codeql-action/commit/cef2e7a910879f4626a24b251504bde16bfe4e76"><code>cef2e7a</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3925">#3925</a>
from github/dependabot/github_actions/dot-github/wor...</li>
<li><a
href="https://github.com/github/codeql-action/commit/5e6adf70ed0299cdf20f90e4e37ac5dd30ab7501"><code>5e6adf7</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3936">#3936</a>
from github/dependabot/npm_and_yarn/tmp-0.2.7</li>
<li><a
href="https://github.com/github/codeql-action/commit/ad170e6c4eaf671895978420267d6cb49b66b706"><code>ad170e6</code></a>
Merge branch 'main' into
dependabot/github_actions/dot-github/workflows/actio...</li>
<li><a
href="https://github.com/github/codeql-action/commit/6a37b3a57ac457a679b84930a67c233c15f5ac41"><code>6a37b3a</code></a>
Rebuild</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...87557b9c84dde89fdd9b10e88954ac2f4248e463">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-09 20:40:55 -04:00
dependabot[bot] ad5686a23a Bump gunicorn from 25.3.0 to 26.0.0 (#990)
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 25.3.0 to
26.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/benoitc/gunicorn/releases">gunicorn's
releases</a>.</em></p>
<blockquote>
<h2>26.0.0</h2>
<h2>Breaking Changes</h2>
<ul>
<li><strong>Eventlet worker removed</strong>: The <code>eventlet</code>
worker class has been dropped. Migrate to <code>gevent</code>,
<code>gthread</code>, or <code>tornado</code>.</li>
</ul>
<h2>New Features</h2>
<ul>
<li><strong>ASGI Framework Compatibility Suite</strong>: New end-to-end
compatibility test harness covering Starlette, FastAPI, Litestar, Quart,
Sanic, and BlackSheep. Current grid passes 438/444 tests (98%).</li>
<li><strong>ASGI Test Suite Expansion</strong>: 134 additional ASGI unit
tests covering protocol semantics, lifespan, websockets, and chunked
framing.</li>
</ul>
<h2>Security</h2>
<ul>
<li><strong>HTTP/1.1 Request-Target Validation</strong> (RFC 9112
sections 3.2.3, 3.2.4):
<ul>
<li>Reject <code>authority-form</code> request-target outside
<code>CONNECT</code></li>
<li>Reject <code>asterisk-form</code> request-target outside
<code>OPTIONS</code></li>
<li>Reject <code>relative-reference</code> request-targets</li>
</ul>
</li>
<li><strong>Header Field Hardening</strong> (RFC 9110):
<ul>
<li>Reject control characters in header field-value (section 5.5)</li>
<li>Reject forbidden trailer field-names (section 6.5.1)</li>
<li>Reject <code>Content-Length</code> list form (RFC 9112 section
6.3)</li>
</ul>
</li>
<li><strong>Request Smuggling Hardening</strong>:
<ul>
<li>Tighten keepalive gate and scope <code>finish_body</code> byte
cap</li>
<li>Keep <code>_body_receiver</code> alive across the keepalive
smuggling gate so pipelined requests cannot re-enter a closed body</li>
<li>Address parser/protocol findings from a six-point WSGI/ASGI
audit</li>
</ul>
</li>
<li><strong>PROXY Protocol (ASGI)</strong>: Enforce
<code>proxy_allow_ips</code> and tighten v1/v2 parsing in the ASGI
callback parser.</li>
<li><strong>Connection Draining</strong>: Drain the connection on close
per RFC 9112 section 9.6 to prevent reset-on-close truncation.</li>
</ul>
<h2>Bug Fixes</h2>
<ul>
<li><strong>Body Framing on HEAD/204/304</strong>:
<ul>
<li>Keep <code>Content-Length</code> on HEAD and 304 responses (<a
href="https://redirect.github.com/benoitc/gunicorn/issues/3621">#3621</a>)</li>
<li>Drop body framing on HEAD/204/304 even when the framework set
it</li>
<li>Warn once when an ASGI app emits a body for a no-body response</li>
</ul>
</li>
<li><strong>HTTP/2 ASGI</strong>:
<ul>
<li>Fix <code>_handle_stream_ended</code> to set
<code>_body_complete</code> in the async HTTP/2 handler so request
bodies finalize correctly on stream end</li>
<li>Add <code>InvalidChunkExtension</code> mapping and fast-parser
support in ASGI tests (<a
href="https://redirect.github.com/benoitc/gunicorn/issues/3565">#3565</a>)</li>
</ul>
</li>
<li><strong>HTTP/1.1 100-Continue</strong>: Stop adding
<code>Transfer-Encoding: chunked</code> to 100-Continue interim
responses.</li>
<li><strong>WebSocket Close Handshake</strong> (RFC 6455):
<ul>
<li>Comply with the close handshake state machine</li>
<li>Close the transport after the close handshake completes</li>
<li>Fix binary send when the <code>text</code> key is
<code>None</code></li>
</ul>
</li>
<li><strong>Early Hints</strong>: Validate headers in the
<code>early_hints</code> callback to match <code>process_headers</code>;
pass only the header name to <code>InvalidHeader</code> (<a
href="https://redirect.github.com/benoitc/gunicorn/issues/3588">#3588</a>).</li>
<li><strong>ASGI Framework Fixes</strong>:
<ul>
<li>Fix ASGI disconnect handling for Django-style apps</li>
<li>Fix Litestar request handling (use raw ASGI receive for
body/headers)</li>
<li>Fix Litestar HTTP endpoints for compatibility tests</li>
<li>Fix Quart headers endpoint to normalize keys to lowercase</li>
<li>Fix Quart WebSocket close test app (missing
<code>accept()</code>)</li>
<li>Fix duplicate <code>Transfer-Encoding</code> header for BlackSheep
streaming</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/benoitc/gunicorn/commit/5d819cf36040f6cc6175fcc804d703fb899509dd"><code>5d819cf</code></a>
release: 26.0.0</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/b45c70df105f7d5dcbc5abfb732804d6464edc21"><code>b45c70d</code></a>
Merge pull request <a
href="https://redirect.github.com/benoitc/gunicorn/issues/3611">#3611</a>
from zc-mattcen/docs-typo</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/99c8d48acf453deb5c49fe12e195dbc00d888d1e"><code>99c8d48</code></a>
Merge pull request <a
href="https://redirect.github.com/benoitc/gunicorn/issues/3623">#3623</a>
from benoitc/chore/drop-eventlet-add-h2-uvloop-test-...</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/5a655af50f20e005dd9e32e6078dc82fa45f3d4b"><code>5a655af</code></a>
Merge pull request <a
href="https://redirect.github.com/benoitc/gunicorn/issues/3622">#3622</a>
from benoitc/test/docker-port-and-ipv4-fixes</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/201df19a8011c0a1d6a0e75ebe22e89d48eb935e"><code>201df19</code></a>
chore: remove eventlet worker; add h2 and uvloop to test deps</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/f4ac8e1f1bf1d365e77f41915da55bec31873f84"><code>f4ac8e1</code></a>
test: pass action name to dirty client and stabilize after TTOU
spam</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/54d38afddf1f0db0c15b5f4ff63f3c7bfad96961"><code>54d38af</code></a>
test: unblock docker fixtures on macOS hosts</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/68843c8893dd938456f0a2da62085ab5776f8871"><code>68843c8</code></a>
Merge pull request <a
href="https://redirect.github.com/benoitc/gunicorn/issues/3621">#3621</a>
from benoitc/fix/asgi-preserve-content-length-on-hea...</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/31f2618f733cc0c78690df63f4e344aaf3f56b20"><code>31f2618</code></a>
Merge pull request <a
href="https://redirect.github.com/benoitc/gunicorn/issues/3620">#3620</a>
from benoitc/fix/asgi-proxy-protocol-trust-and-parsing</li>
<li><a
href="https://github.com/benoitc/gunicorn/commit/41ec7527dbd8a9e52728477700707ad40e41d9dc"><code>41ec752</code></a>
fix: keep Content-Length on HEAD and 304 responses</li>
<li>Additional commits viewable in <a
href="https://github.com/benoitc/gunicorn/compare/25.3.0...26.0.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gunicorn&package-manager=uv&previous-version=25.3.0&new-version=26.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-09 20:40:23 -04:00
Alex 3d18320096 Update readme (#1000) 2026-05-14 14:46:43 +01:00
Alex 3ac8d9f681 Update urllib3 to 2.7.0 (#986) 2026-05-12 12:25:39 +01:00
Alex 2f9b42f428 Clarify Docker digest update group (#992) 2026-05-12 12:21:15 +01:00
Alex 5a53d5910d Update dependabot check timings (#987) 2026-05-12 12:11:12 +01:00
158 changed files with 9322 additions and 1287 deletions
+8
View File
@@ -42,7 +42,15 @@ updates:
open-pull-requests-limit: 5
groups:
docker-base-image-digests:
# Exclude python from the group on purpose. Dependabot's Docker
# pre-release filter is bypassed for *grouped* updates
# (dependabot-core#9496), so a grouped python update proposes pre-release
# tags like python:3.15.0b2 as if they were a normal stable minor bump.
# Updated individually, python is filtered correctly: alpha/beta/rc tags
# are skipped and only stable releases (e.g. 3.15.0 once final) are
# proposed. node + uv stay grouped into a single digest PR.
patterns: ["*"]
exclude-patterns: ["python"]
ignore:
# Node.js: block major-version bumps so dependabot never proposes
# moving from one LTS line to a non-LTS "Current" release (e.g. 24 -> 25).
@@ -67,10 +67,10 @@ jobs:
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Log in to the Container registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@@ -78,7 +78,13 @@ jobs:
- name: Extract metadata for ${{ matrix.target }} image
id: meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
env:
# Annotate both the per-platform manifests and the multi-arch image
# index. The index level is what manifest-list consumers (Renovate's
# minimumReleaseAge soak check, provenance/SBOM tooling) read for the
# standard org.opencontainers.image.* annotations, including `created`.
DOCKER_METADATA_ANNOTATIONS_LEVELS: index,manifest
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.image_name_suffix }}
tags: |
@@ -90,11 +96,11 @@ jobs:
type=ref,event=tag
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Build and push ${{ matrix.target }} Docker image
id: push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
platforms: linux/amd64,linux/arm64
context: .
@@ -105,10 +111,11 @@ jobs:
RELEASE_VERSION=${{ github.ref_name }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
- name: Generate artifact attestation for ${{ matrix.target }} image
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}${{ matrix.image_name_suffix }}
subject-digest: ${{ steps.push.outputs.digest }}
@@ -127,14 +134,14 @@ jobs:
LEGACY_NAME: calibre-web-automated-book-downloader
steps:
- name: Log in to registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Create legacy aliases
run: |
+15 -15
View File
@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install uv and Python
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
version: "0.11.3"
python-version: "3.14"
@@ -39,10 +39,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install uv and Python
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
version: "0.11.3"
python-version: "3.14"
@@ -59,10 +59,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install uv and Python
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
version: "0.11.3"
python-version: "3.14"
@@ -78,13 +78,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Build shelfmark-lite image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
target: shelfmark-lite
@@ -99,10 +99,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: "npm"
@@ -122,10 +122,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: "npm"
@@ -142,10 +142,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: "npm"
+4 -4
View File
@@ -22,17 +22,17 @@ jobs:
language: [python, javascript-typescript]
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Initialize CodeQL
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v3
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v3
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v3
uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v3
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v3
with:
category: "/language:${{ matrix.language }}"
+130
View File
@@ -0,0 +1,130 @@
name: E2E Platform
# Hermetic end-to-end matrix: boots the app under test against mock
# Anna's Archive / Cloudflare / bypasser / DNS / proxy / Tor / real torrent
# clients and runs the cluster suite under each config profile.
#
# On a PR that touches relevant code, this runs a fast core subset *and* the heavy
# `full` profile (real Chrome solving Cloudflare + DoH + real qBittorrent). The
# `e2e-required` job aggregates them into ONE status check — make that check a
# required status check in branch protection to block merges on any e2e failure
# (see tests/e2e/platform/README.md "Gating PRs").
on:
pull_request:
schedule:
- cron: "0 4 * * *" # nightly full matrix
workflow_dispatch:
concurrency:
group: e2e-platform-${{ github.ref }}
cancel-in-progress: true
jobs:
# Detect whether anything that affects the e2e platform changed. This lets the
# required check always report (never stuck "pending") while only spending CI on
# PRs that can actually break the e2e stack.
changes:
runs-on: ubuntu-latest
outputs:
relevant: ${{ steps.filter.outputs.relevant }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4.0.2
id: filter
with:
filters: |
relevant:
- 'shelfmark/**'
- 'entrypoint.sh'
- 'tor.sh'
- 'Dockerfile'
- 'tests/e2e/platform/**'
- '.github/workflows/e2e-platform.yml'
select-profiles:
needs: changes
if: needs.changes.outputs.relevant == 'true' || github.event_name != 'pull_request'
runs-on: ubuntu-latest
outputs:
profiles: ${{ steps.pick.outputs.profiles }}
steps:
- id: pick
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo 'profiles=["baseline","bypasser-external","dns-blocked"]' >> "$GITHUB_OUTPUT"
else
echo 'profiles=["baseline","bypasser-external","bypasser-disabled","dns-manual","dns-blocked","dns-doh","proxy-http","proxy-socks","tor","client-transmission","client-deluge","client-qbittorrent-delayed"]' >> "$GITHUB_OUTPUT"
fi
e2e:
needs: select-profiles
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
profile: ${{ fromJSON(needs.select-profiles.outputs.profiles) }}
name: e2e (${{ matrix.profile }})
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install uv and Python
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: "3.14"
enable-cache: true
- name: Sync dependencies
run: make install-python-dev
- name: Run e2e platform (${{ matrix.profile }})
run: tests/e2e/platform/run-e2e.sh env/${{ matrix.profile }}.env
- name: Dump shelfmark logs on failure
if: failure()
run: cat tests/e2e/platform/.state/shelfmark.${{ matrix.profile }}.log || true
# Heavy "everything real" job: real Chrome internal bypasser solving Cloudflare +
# DoH + real qBittorrent webseed download. Runs on relevant PRs and nightly.
e2e-full:
needs: changes
if: needs.changes.outputs.relevant == 'true' || github.event_name != 'pull_request'
runs-on: ubuntu-latest
name: e2e (full — real Chrome + qBittorrent)
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install uv and Python
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: "3.14"
enable-cache: true
- name: Sync dependencies
run: make install-python-dev
- name: Run full pipeline
run: tests/e2e/platform/run-e2e.sh env/full.env
- name: Dump logs on failure
if: failure()
run: |
cat tests/e2e/platform/.state/shelfmark.full.log || true
docker logs e2e-qbittorrent || true
# Single aggregated gate. ALWAYS runs (so a required check never hangs "pending"
# on unrelated PRs) and FAILS if any e2e job failed/was cancelled. Make THIS the
# required status check in branch protection.
e2e-required:
name: e2e required
needs: [e2e, e2e-full]
if: always()
runs-on: ubuntu-latest
steps:
- name: Aggregate e2e results
run: |
matrix='${{ needs.e2e.result }}'
full='${{ needs.e2e-full.result }}'
echo "e2e matrix=$matrix, e2e-full=$full"
# success or skipped (unrelated PR) is OK; failure/cancelled blocks.
for r in "$matrix" "$full"; do
if [ "$r" = "failure" ] || [ "$r" = "cancelled" ]; then
echo "::error::An e2e platform job did not pass — blocking."
exit 1
fi
done
echo "All e2e platform jobs passed (or were skipped as not relevant)."
+4
View File
@@ -166,6 +166,10 @@ ENV/
env.bak/
venv.bak/
# ...but the e2e platform test profiles live in an env/ dir and must be tracked
!tests/e2e/platform/env/
!tests/e2e/platform/env/*.env
# Spyder project settings
.spyderproject
.spyproject
+49 -11
View File
@@ -4,7 +4,7 @@ ARG BUILDPLATFORM
ARG BUILDARCH
# Frontend build stage.
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f AS frontend-builder
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd AS frontend-builder
# Helpful debug output to see what platforms BuildKit thinks it's using
RUN echo "BUILDPLATFORM=$BUILDPLATFORM BUILDARCH=$BUILDARCH TARGETPLATFORM=$TARGETPLATFORM TARGETARCH=$TARGETARCH"
@@ -25,7 +25,7 @@ COPY src/frontend/ ./
RUN npm run build
# Use python-slim as the base image
FROM python:3.14-slim@sha256:1697e8e8d39bf168e177ac6b5fdab6df86d81cfc24dae17dfb96cfc3ef76b4dd AS base
FROM python:3.14.6-slim@sha256:d3400aa122fa42cf0af0dbe8ec3091b047eac5c8f7e3539f7135e86d855dc015 AS base
COPY --from=ghcr.io/astral-sh/uv:0.11.3@sha256:90bbb3c16635e9627f49eec6539f956d70746c409209041800a0280b93152823 /uv /uvx /bin/
@@ -72,7 +72,12 @@ RUN apt-get update && \
# --- Tor support (activated via USING_TOR=true) ---
tor \
supervisor \
iptables && \
iptables \
# --- WireGuard support (activated via USING_WIREGUARD=true) ---
wireguard-tools \
iproute2 \
procps \
ca-certificates && \
# Configure iptables alternatives for tor.sh compatibility
update-alternatives --set iptables /usr/sbin/iptables-legacy && \
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy && \
@@ -131,7 +136,7 @@ RUN mkdir -p \
ln -s /tmp/shelfmark/seleniumbase/archived_files /app/archived_files && \
chown -R 1000:1000 /config /books /home/shelfmark /tmp/shelfmark /var/log/shelfmark && \
chmod -R a+rX /app && \
chmod +x /app/entrypoint.sh /app/tor.sh /app/genDebug.sh
chmod +x /app/entrypoint.sh /app/tor.sh /app/wireguard.sh /app/genDebug.sh
# Expose the application port
EXPOSE ${FLASK_PORT}
@@ -147,21 +152,39 @@ ENTRYPOINT ["/usr/bin/dumb-init", "--"]
FROM base AS shelfmark
RUN apt-get update && \
apt-get install -y --no-install-recommends \
# --- Chromium (PINNED to 149.0.7827.196) ---
# Debian's chromium 150.0.7871.46-1~deb13u1 security update (trixie-security,
# 2026-07-05) no longer opens the DevTools remote-debugging TCP port at all
# (no listener, no DevToolsActivePort file, even with a custom --user-data-dir;
# the RemoteDebuggingAllowed policy does not restore it). The SeleniumBase
# Pure-CDP driver connects through that port (/json/version), so with 150 every
# internal bypass dies with "Pure CDP browser startup failed" and all
# CF-gated downloads fail. Install the last working version from
# snapshot.debian.org until the bypasser can talk to Chromium >= 150 (e.g.
# pipe-based DevTools / UC mode) or seleniumbase ships a fix.
# Chrome 144+ requires --enable-unsafe-swiftshader for WebGL in Docker.
# This flag is set in internal_bypasser.py _get_browser_args()
ARG CHROMIUM_VERSION=149.0.7827.196-1~deb13u1
ARG CHROMIUM_SNAPSHOT=20260704T000000Z
RUN echo "deb [check-valid-until=no] https://snapshot.debian.org/archive/debian-security/${CHROMIUM_SNAPSHOT}/ trixie-security main" \
> /etc/apt/sources.list.d/chromium-pin-snapshot.list && \
apt-get update -o Acquire::Retries=5 && \
apt-get install -y --no-install-recommends -o Acquire::Retries=5 \
# For dumb display
xvfb \
# For screen recording
ffmpeg \
# --- Chromium (unpinned - uses latest from Debian repos) ---
# Chrome 144+ requires --enable-unsafe-swiftshader for WebGL in Docker.
# This flag is set in internal_bypasser.py _get_browser_args()
chromium \
chromium-common \
chromium=${CHROMIUM_VERSION} \
chromium-common=${CHROMIUM_VERSION} \
# For tkinter (pyautogui)
python3-tk \
# For RAR extraction
unrar-free && \
# Keep apt from "upgrading" chromium past the pin inside derived images
printf 'Package: chromium chromium-common\nPin: version %s\nPin-Priority: 1001\n' "${CHROMIUM_VERSION}" \
> /etc/apt/preferences.d/chromium-pin && \
rm /etc/apt/sources.list.d/chromium-pin-snapshot.list && \
# Create symlink so rarfile library can find unrar
ln -sf /usr/bin/unrar-free /usr/bin/unrar && \
# Cleanup APT cache
@@ -173,6 +196,21 @@ RUN apt-get update && \
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-default-groups --extra browser
# Deterministically resolve the Xlib namespace collision.
# pyautogui/mouseinfo pull the stale `python3-xlib` (0.15, 2014), while the
# `--extra browser` set pulls `python-xlib` (0.33). Both packages install into
# the same top-level `Xlib/` namespace, so whichever lands last wins. When the
# 2014 build wins, `Xlib.X` is missing `FamilyServerInterpreted`, which the
# SeleniumBase Pure-CDP driver requires at browser startup -> every bypass fails
# with "module 'Xlib.X' has no attribute 'FamilyServerInterpreted'" and no
# Cloudflare/DDoS-Guard protected download can complete. Drop the stale package
# and force python-xlib 0.33 to own the namespace. pyautogui runs fine against
# 0.33 (superset API).
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip uninstall --python /app/.venv/bin/python python3-xlib && \
uv pip install --python /app/.venv/bin/python --reinstall python-xlib==0.33 && \
/app/.venv/bin/python -c "import Xlib.X; assert hasattr(Xlib.X, 'FamilyServerInterpreted'), 'Xlib.X.FamilyServerInterpreted missing after fix'; print('Xlib namespace OK:', Xlib.__version__)"
# uv is only needed while building the image.
RUN rm -f /usr/bin/uv /usr/bin/uvx
+29 -1
View File
@@ -1,4 +1,4 @@
.PHONY: help install install-ci install-python-dev dev build preview frontend-typecheck frontend-lint frontend-format frontend-format-fix frontend-checks frontend-test clean up down docker-build refresh restart build-serve python-lint python-lint-fix python-format python-format-fix python-typecheck python-dead-code python-checks python-test python-test-cov checks fix
.PHONY: help install install-ci install-python-dev dev build preview frontend-typecheck frontend-lint frontend-format frontend-format-fix frontend-checks frontend-test clean up down docker-build refresh restart build-serve python-lint python-lint-fix python-format python-format-fix python-typecheck python-dead-code python-checks python-test python-test-cov e2e-platform e2e-platform-profile e2e-platform-matrix e2e-platform-full e2e-platform-build checks fix
# Frontend directory
FRONTEND_DIR := src/frontend
@@ -38,6 +38,10 @@ help:
@echo " python-checks - Run all Python static analysis checks"
@echo " python-test - Run unit tests"
@echo " python-test-cov - Run unit tests with coverage report"
@echo " e2e-platform - Run e2e docker platform (baseline profile)"
@echo " e2e-platform-profile PROFILE=<name> - Run e2e platform for one profile"
@echo " e2e-platform-matrix - Run e2e platform across all config profiles"
@echo " e2e-platform-full - Run heavy 'full' profile (real Chrome bypasser + DoH + real qBittorrent)"
@echo " clean - Remove node_modules and build artifacts"
@echo ""
@echo "Backend (Docker):"
@@ -127,6 +131,30 @@ python-test-cov:
@echo "Running tests with coverage..."
uv run pytest tests/ -x --tb=short -m "not integration and not e2e" --cov --cov-report=term-missing
# E2E docker platform: hermetic stack (mock AA/Cloudflare/bypasser/DNS/proxy/Tor)
# exercised across config profiles. See tests/e2e/platform/README.md.
E2E_PLATFORM_DIR := tests/e2e/platform
e2e-platform:
@echo "Running e2e platform (baseline profile)..."
cd $(E2E_PLATFORM_DIR) && ./run-e2e.sh env/baseline.env
e2e-platform-profile:
@echo "Running e2e platform (profile=$(PROFILE))..."
cd $(E2E_PLATFORM_DIR) && ./run-e2e.sh env/$(PROFILE).env
e2e-platform-matrix:
@echo "Running e2e platform matrix (all profiles)..."
cd $(E2E_PLATFORM_DIR) && ./run-matrix.sh
e2e-platform-build:
@echo "Pre-building e2e platform images once (reused across profiles)..."
cd $(E2E_PLATFORM_DIR) && ./build-images.sh
e2e-platform-full:
@echo "Running e2e platform FULL profile (real Chrome bypasser + DoH + real qBittorrent)..."
cd $(E2E_PLATFORM_DIR) && ./run-e2e.sh env/full.env
# Frontend linting
frontend-lint:
@echo "Running Oxlint..."
+43
View File
@@ -0,0 +1,43 @@
# Routes all traffic through a WireGuard tunnel - requires root startup.
#
# Mount your wg-quick config at /config/wg0.conf (read-only is fine). All
# non-LAN egress is forced through the tunnel by an iptables kill-switch, so if
# the tunnel drops, external traffic fails closed. LAN ranges (WebUI + internal
# download clients like Prowlarr / qBittorrent) stay reachable off-tunnel.
services:
shelfmark-wireguard:
image: ghcr.io/calibrain/shelfmark:latest
environment:
FLASK_PORT: 8084
# Quoted so it is passed as the literal string "true": entrypoint.sh compares
# $USING_WIREGUARD against "true", and some Compose implementations stringify
# a bare YAML boolean as "True", which would silently NOT enable WireGuard.
USING_WIREGUARD: "true"
# Path to the mounted wg-quick config (default shown).
WIREGUARD_CONFIG: /config/wg0.conf
# CIDRs kept OFF the tunnel so the WebUI and internal clients stay reachable.
LAN_NETWORK: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
PUID: 1000
PGID: 1000
cap_add:
- NET_ADMIN
- NET_RAW
# WireGuard needs the module/kernel routing; NET_ADMIN covers wg-quick.
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
# Disable IPv6 in the container so the kill-switch can guarantee no IPv6
# leak path on kernels/containers without a usable ip6tables. wireguard.sh
# fails closed if IPv6 is neither kill-switched nor disabled. If your host
# DOES have a working ip6tables you may omit these (an ip6tables kill-switch
# is installed instead); or set WIREGUARD_ALLOW_IPV6_LEAK=true only if the
# container genuinely has no IPv6 connectivity.
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv6.conf.default.disable_ipv6=1
ports:
- 8084:8084
restart: unless-stopped
volumes:
- /path/to/books:/books # Default destination for book downloads
- /path/to/config:/config # App configuration (put wg0.conf here)
# Required for torrent / usenet - path must match your download client's volume exactly
# - /path/to/downloads:/path/to/downloads
+25
View File
@@ -0,0 +1,25 @@
# Local development - WireGuard variant
services:
shelfmark-wireguard-dev:
extends:
file: ./compose/docker-compose.wireguard.yml
service: shelfmark-wireguard
build:
context: .
dockerfile: Dockerfile
target: shelfmark
environment:
# Quoted so they are passed as the literal string "true" (entrypoint.sh and
# the app compare against "true"); a bare YAML boolean can be stringified as
# "True" by some Compose variants, silently disabling the feature.
DEBUG: "true"
USING_WIREGUARD: "true"
WIREGUARD_CONFIG: /config/wg0.conf
volumes:
- ./.local/config:/config
- ./.local/books:/books
- ./.local/log:/var/log/shelfmark
- ./.local/tmp:/tmp/shelfmark
# Place your wg-quick config at ./.local/config/wg0.conf
# Required for torrent / usenet - path must match your download client's volume exactly
# - /path/to/downloads:/path/to/downloads
+4
View File
@@ -91,6 +91,10 @@ Example:
- Shelfmark can see the same files at `/downloads/books/...`
- Add a mapping from Remote Path `/data/torrents` to Local Path `/downloads`
If the files are copied or synced into Shelfmark on a delay, increase **Completed Path Wait (seconds)**
in Settings -> Advanced. The default is 60 seconds; seedbox or remote-sync setups may need a value
longer than the sync interval.
## File Processing Options
### Transfer Method (Torrent / Usenet Only)
+117 -2
View File
@@ -7,6 +7,7 @@ This document lists all configuration options that can be set via environment va
## Table of Contents
- [Bootstrap Configuration](#bootstrap-configuration)
- [Egress / VPN Routing](#egress--vpn-routing)
- [General](#general)
- [Search Mode](#search-mode)
- [Downloads](#downloads)
@@ -145,6 +146,98 @@ Show the onboarding wizard on first run. Set to false to skip (useful for epheme
</details>
## Egress / VPN Routing
These startup-only variables are consumed by `entrypoint.sh` / `wireguard.sh` to select and configure the WireGuard transparent-egress kill-switch. `USING_WIREGUARD` and [`USING_TOR`](#using_tor) (documented under Network) are mutually exclusive; both require root startup.
| Variable | Description | Type | Default |
|----------|-------------|------|---------|
| `USING_WIREGUARD` | Route all traffic through a WireGuard VPN tunnel with a fail-closed iptables kill-switch (non-tunnel egress is dropped). Requires root startup and NET_ADMIN (plus NET_RAW). Mutually exclusive with USING_TOR. | boolean | `false` |
| `WIREGUARD_CONFIG` | Path to the mounted wg-quick configuration file. | string (path) | `/config/wg0.conf` |
| `WIREGUARD_INTERFACE` | WireGuard interface name brought up by wg-quick. | string | `wg0` |
| `LAN_NETWORK` | Comma-separated CIDRs kept off the tunnel so the WebUI and internal download clients (Prowlarr, qBittorrent) stay reachable. | string (comma-separated) | `127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` |
| `WIREGUARD_ENFORCE_DNS` | Pin the container's resolver so DNS cannot silently fall back to an off-tunnel path. The resolver used is WIREGUARD_DNS if set, else the tunnel config's DNS = line. This does NOT force queries through the tunnel: it is designed for a trusted LAN resolver kept reachable off-tunnel via LAN_NETWORK (the query leaves over the LAN; the resolver encrypts upstream while the download still egresses via the tunnel). Special case: when Docker's embedded resolver (nameserver 127.0.0.11) is present, it is PRESERVED so container-name resolution (e.g. prowlarr, qbittorrent) keeps working, and the embedded resolver's upstream must be pinned via the container's compose dns: list. Fails closed (refuses to start) only when no embedded resolver is present AND no resolver is defined, or /etc/resolv.conf is not writable. | boolean | `true` |
| `WIREGUARD_DNS` | Explicit resolver(s) (comma/space separated) to pin when WIREGUARD_ENFORCE_DNS is true and Docker's embedded resolver is NOT in use. Use when the VPN's pushed DNS filters domains you need; point it at a resolver reachable via the tunnel or an allowed LAN resolver. NOTE: when the embedded resolver (127.0.0.11) is present it is preserved and this value cannot repoint its upstream from inside the container — set the container's compose dns: list to the trusted resolver instead. | string (comma-separated) | `unset (uses config DNS = line)` |
| `WIREGUARD_DISABLE_IPV6` | Strip IPv6 Address/AllowedIPs/DNS from the tunnel config before wg-quick (many container kernels lack the ip6tables raw table wg-quick needs) and remove IPv6 as a leak surface. | boolean | `true` |
| `WIREGUARD_ALLOW_IPV6_LEAK` | Escape hatch: continue startup even when an IPv6 kill-switch cannot be installed AND IPv6 cannot be disabled. Only set when the container has no IPv6 connectivity, as IPv6 egress may otherwise bypass the tunnel. | boolean | `false` |
| `WIREGUARD_ALLOW_WEBUI_OFFTUNNEL` | When false (default) the kill-switch is strictly fail-closed: the only off-tunnel egress permitted is loopback, the tunnel device and the LAN allowlist. Set true only if a NON-LAN client (e.g. a public reverse proxy on a different segment) must reach the WebUI; it permits app-server REPLY packets (--sport FLASK_PORT, conntrack REPLY) to leave off-tunnel. Server replies only, never client-initiated egress, so it cannot leak outbound browsing/downloads or the real IP for outbound requests, but it is still an off-tunnel path while the tunnel is down, hence opt-in. LAN WebUI clients never need it (covered by LAN_NETWORK). | boolean | `false` |
| `WIREGUARD_STALE_AFTER` | Seconds since the last WireGuard handshake before the healthcheck bounces the tunnel. | number | `180` |
<details>
<summary>Detailed descriptions</summary>
#### `USING_WIREGUARD`
Route all traffic through a WireGuard VPN tunnel with a fail-closed iptables kill-switch (non-tunnel egress is dropped). Requires root startup and NET_ADMIN (plus NET_RAW). Mutually exclusive with USING_TOR.
- **Type:** boolean
- **Default:** `false`
#### `WIREGUARD_CONFIG`
Path to the mounted wg-quick configuration file.
- **Type:** string (path)
- **Default:** `/config/wg0.conf`
#### `WIREGUARD_INTERFACE`
WireGuard interface name brought up by wg-quick.
- **Type:** string
- **Default:** `wg0`
#### `LAN_NETWORK`
Comma-separated CIDRs kept off the tunnel so the WebUI and internal download clients (Prowlarr, qBittorrent) stay reachable.
- **Type:** string (comma-separated)
- **Default:** `127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`
#### `WIREGUARD_ENFORCE_DNS`
Pin the container's resolver so DNS cannot silently fall back to an off-tunnel path. The resolver used is WIREGUARD_DNS if set, else the tunnel config's DNS = line. This does NOT force queries through the tunnel: it is designed for a trusted LAN resolver kept reachable off-tunnel via LAN_NETWORK (the query leaves over the LAN; the resolver encrypts upstream while the download still egresses via the tunnel). Special case: when Docker's embedded resolver (nameserver 127.0.0.11) is present, it is PRESERVED so container-name resolution (e.g. prowlarr, qbittorrent) keeps working, and the embedded resolver's upstream must be pinned via the container's compose dns: list. Fails closed (refuses to start) only when no embedded resolver is present AND no resolver is defined, or /etc/resolv.conf is not writable.
- **Type:** boolean
- **Default:** `true`
#### `WIREGUARD_DNS`
Explicit resolver(s) (comma/space separated) to pin when WIREGUARD_ENFORCE_DNS is true and Docker's embedded resolver is NOT in use. Use when the VPN's pushed DNS filters domains you need; point it at a resolver reachable via the tunnel or an allowed LAN resolver. NOTE: when the embedded resolver (127.0.0.11) is present it is preserved and this value cannot repoint its upstream from inside the container — set the container's compose dns: list to the trusted resolver instead.
- **Type:** string (comma-separated)
- **Default:** `unset (uses config DNS = line)`
#### `WIREGUARD_DISABLE_IPV6`
Strip IPv6 Address/AllowedIPs/DNS from the tunnel config before wg-quick (many container kernels lack the ip6tables raw table wg-quick needs) and remove IPv6 as a leak surface.
- **Type:** boolean
- **Default:** `true`
#### `WIREGUARD_ALLOW_IPV6_LEAK`
Escape hatch: continue startup even when an IPv6 kill-switch cannot be installed AND IPv6 cannot be disabled. Only set when the container has no IPv6 connectivity, as IPv6 egress may otherwise bypass the tunnel.
- **Type:** boolean
- **Default:** `false`
#### `WIREGUARD_ALLOW_WEBUI_OFFTUNNEL`
When false (default) the kill-switch is strictly fail-closed: the only off-tunnel egress permitted is loopback, the tunnel device and the LAN allowlist. Set true only if a NON-LAN client (e.g. a public reverse proxy on a different segment) must reach the WebUI; it permits app-server REPLY packets (--sport FLASK_PORT, conntrack REPLY) to leave off-tunnel. Server replies only, never client-initiated egress, so it cannot leak outbound browsing/downloads or the real IP for outbound requests, but it is still an off-tunnel path while the tunnel is down, hence opt-in. LAN WebUI clients never need it (covered by LAN_NETWORK).
- **Type:** boolean
- **Default:** `false`
#### `WIREGUARD_STALE_AFTER`
Seconds since the last WireGuard handshake before the healthcheck bounces the tunnel.
- **Type:** number
- **Default:** `180`
</details>
## General
| Variable | Description | Type | Default |
@@ -223,6 +316,7 @@ Default language filter for searches.
| `AA_DEFAULT_SORT` | Default sort order for search results. | string (choice) | `relevance` |
| `SHOW_RELEASE_SOURCE_LINKS` | Show clickable release-source links in release and details modals. Metadata provider links stay enabled. | boolean | `true` |
| `SHOW_COMBINED_SELECTOR` | Show the option to search for and download both a book and audiobook together. | boolean | `true` |
| `FORCE_COMBINED_SEARCH` | Force combined search whenever it's available. Locks the combined toggle on. | boolean | `false` |
| `METADATA_PROVIDER` | Choose which metadata provider to use for book searches. | string (choice) | `openlibrary` |
| `METADATA_PROVIDER_AUDIOBOOK` | Metadata provider for audiobook searches. Uses the book provider if not set. | string (choice) | _empty string_ |
| `METADATA_PROVIDER_COMBINED` | Metadata provider for combined mode searches. Uses the book provider if not set. | string (choice) | _empty string_ |
@@ -270,6 +364,15 @@ Show the option to search for and download both a book and audiobook together.
- **Type:** boolean
- **Default:** `true`
#### `FORCE_COMBINED_SEARCH`
**Always Use Combined Search**
Force combined search whenever it's available. Locks the combined toggle on.
- **Type:** boolean
- **Default:** `false`
#### `METADATA_PROVIDER`
**Book Metadata Provider**
@@ -948,6 +1051,7 @@ Comma-separated hosts to bypass proxy (e.g., localhost,127.0.0.1,10.*,*.local)
| `CUSTOM_SCRIPT` | Path to a script to run after each successful download. Must be executable. | string | _none_ |
| `CUSTOM_SCRIPT_PATH_MODE` | Pass the path to the custom script as an absolute path or relative to the destination folder. | string (choice) | `absolute` |
| `CUSTOM_SCRIPT_JSON_PAYLOAD` | Send a JSON payload to the script via stdin. Useful for multi-file imports (audiobooks) or richer metadata without relying on path parsing. | boolean | `false` |
| `DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT` | How long to wait after a torrent or usenet client reports completion for the completed file path to become visible to Shelfmark. Increase this for seedbox or remote-sync workflows. | number | `60` |
| `COVERS_CACHE_ENABLED` | Cache book covers on the server for faster loading. | boolean | `true` |
| `COVERS_CACHE_TTL` | How long to keep cached covers. Set to 0 to keep forever (recommended for static artwork). | number | `0` |
| `COVERS_CACHE_MAX_SIZE_MB` | Maximum disk space for cached covers. Oldest images are removed when limit is reached. | number | `500` |
@@ -1028,6 +1132,16 @@ Send a JSON payload to the script via stdin. Useful for multi-file imports (audi
- **Type:** boolean
- **Default:** `false`
#### `DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT`
**Completed Path Wait (seconds)**
How long to wait after a torrent or usenet client reports completion for the completed file path to become visible to Shelfmark. Increase this for seedbox or remote-sync workflows.
- **Type:** number
- **Default:** `60`
- **Constraints:** min: 0, max: 3600
#### `COVERS_CACHE_ENABLED`
**Enable Cover Cache**
@@ -1283,7 +1397,7 @@ Delay between requests in seconds to avoid rate limiting (0-10).
| `IRC_USE_TLS` | Enable TLS/SSL encryption for the IRC connection. Disable for servers that don't support TLS. | boolean | `true` |
| `IRC_CHANNEL` | Channel name without the # prefix | string | _none_ |
| `IRC_NICK` | Your IRC nickname (required). Must be unique on the IRC network. | string | _none_ |
| `IRC_SEARCH_BOT` | The search bot to query for results | string | _none_ |
| `IRC_SEARCH_BOT` | The search bot to address queries to (required). | string | _none_ |
| `IRC_CACHE_TTL` | How long to keep cached search results before they expire. | string (choice) | `2592000` |
<details>
@@ -1341,10 +1455,11 @@ Your IRC nickname (required). Must be unique on the IRC network.
**Search bot**
The search bot to query for results
The search bot to address queries to (required). Searches are sent as "@<bot> <query>". Without it, queries would be posted unaddressed to the channel.
- **Type:** string
- **Default:** _none_
- **Required:** Yes
#### `IRC_CACHE_TTL`
+16 -2
View File
@@ -30,7 +30,19 @@ Configure in **Settings → Security → Authentication Method → OIDC**.
| Auto-Provision Users | Create accounts on first login | `true` |
| Login Button Label | Custom text for the sign-in button | — |
Use **Test Connection** to verify discovery and client configuration before attempting login.
Use **Test Connection** to verify discovery, client configuration, and the provider's token signing keys (JWKS) before attempting login.
> **Authentik users:** make sure your provider has a **Signing Key** selected (e.g. the default self-signed certificate). Without one, Authentik serves an empty JWKS document and every login fails with an OIDC callback error, even though the discovery document looks healthy.
## Account Linking
On login, Shelfmark matches the OIDC identity to a user account in this order:
1. **OIDC subject** — a user who has logged in through this provider before.
2. **Email** — a local account with the same (unique) email address. This only happens when the provider also asserts `email_verified: true` for the address; an unverified email would let anyone claim a local account by registering its address at the IdP.
3. Otherwise, a new account is created when **Auto-Provision Users** is enabled (username conflicts get a numeric suffix), or the login is rejected with "Account not found" when it is disabled.
If the `email_verified` claim is missing or `false`, email linking is silently skipped — a common surprise when the address was never verified at the identity provider (e.g. Keycloak's **Email verified** toggle on the user, or Authentik accounts created without email verification). Make sure the `email` scope is requested and the address is marked verified in your IdP.
## Environment Variables
@@ -46,6 +58,8 @@ If `DISABLE_LOCAL_AUTH` and `OIDC_AUTO_REDIRECT` are both enabled, users are red
## Troubleshooting
- **No token signing keys (empty JWKS)** — The provider's JWKS endpoint returned no keys, so ID tokens can't be verified. In Authentik this happens when the provider has no **Signing Key** selected; pick one (e.g. the default self-signed certificate) and try again.
- **Issuer validation failed** — The issuer in the token doesn't match the discovery document. Check your provider's external URL / issuer configuration.
- **Callback URL mismatch** — Reverse proxy isn't forwarding `X-Forwarded-Proto` or `X-Forwarded-Host`, so the constructed callback URL doesn't match what's registered in the provider.
- **Account not found** — Auto-provision is disabled and the user hasn't been pre-created by an admin.
- **Account not found** — Auto-provision is disabled and the user hasn't been pre-created by an admin. If you pre-created the account with a matching email, see [Account Linking](#account-linking): the provider must send `email_verified: true` for linking to happen.
- **Login created a duplicate account instead of linking to my local one** — Email linking requires a verified email; see [Account Linking](#account-linking). With `DEBUG=true`, the log notes when linking is skipped because the address isn't verified.
+8 -1
View File
@@ -19,7 +19,7 @@ http://your-server:8084/?q=harry+potter
| `lang` | Filter by language (ISO 639-1 code) | `/?lang=en` |
| `format` | Filter by file format | `/?format=epub` |
| `content` | Filter by content type | `/?content=fiction` |
| `content_type` | Select media type (`ebook` or `audiobook`) in Universal mode only | `/?q=dune&content_type=audiobook` |
| `content_type` | Select media type (`ebook`, `audiobook`, or `combined`) in Universal mode only | `/?q=dune&content_type=audiobook` |
| `sort` | Sort order for results | `/?sort=newest` |
## Multiple Values
@@ -63,6 +63,11 @@ Some parameters support multiple values by repeating the parameter:
/?q=dune&content_type=audiobook
```
**Universal search forcing combined (ebook + audiobook):**
```
/?q=dune&content_type=combined
```
## Search Mode Behavior
### Direct Mode
@@ -74,6 +79,8 @@ When Search Mode is set to Direct, all parameters are used to filter results fro
`q`, `sort`, and `content_type` are used. Other parameters (author, title, format, etc.) are silently ignored since metadata providers have their own search capabilities.
`content_type=combined` forces combined mode (search ebook and audiobook providers together), overriding the last-used preference. It is silently ignored if combined mode is unavailable (e.g. the combined selector is disabled in settings, or either content type is blocked by request policy).
## Notes
- URL parameters are read once on page load
+27 -1
View File
@@ -81,6 +81,13 @@ if is_truthy "$ENABLE_LOGGING_VALUE"; then
fi
fi
# Egress modes are mutually exclusive. Check this BEFORE starting either one so
# we never run tor.sh and then abort, leaving a half-configured network stack.
if [ "$USING_TOR" = "true" ] && [ "$USING_WIREGUARD" = "true" ]; then
echo "USING_TOR and USING_WIREGUARD are mutually exclusive; enable only one egress mode." >&2
exit 1
fi
if [ "$USING_TOR" = "true" ]; then
if [ "$RUN_AS_NON_ROOT" = "true" ]; then
echo "USING_TOR=true requires the container to start as root." >&2
@@ -90,6 +97,15 @@ if [ "$USING_TOR" = "true" ]; then
./tor.sh
fi
if [ "$USING_WIREGUARD" = "true" ]; then
if [ "$RUN_AS_NON_ROOT" = "true" ]; then
echo "USING_WIREGUARD=true requires the container to start as root." >&2
echo "Non-root mode skips the privileged network setup WireGuard depends on." >&2
exit 1
fi
./wireguard.sh
fi
if [ "$FILE_LOGGING_ENABLED" = "true" ]; then
start_file_logging "$LOG_FILE"
fi
@@ -235,7 +251,11 @@ test_write() {
return 1
fi
if ! run_as_target_user sh -c 'echo 0123456789_TEST > "$1"' _ "$test_file"; then
# This is a probe: a failure here is expected (e.g. a fresh root-owned bind
# mount) and is recovered by the caller via change_ownership + re-probe. Hide
# the shell's "Permission denied"/"Read-only file system" stderr so a handled
# probe miss doesn't masquerade as a real boot failure in the logs.
if ! run_as_target_user sh -c 'echo 0123456789_TEST 2>/dev/null > "$1"' _ "$test_file"; then
echo "Failed to write test file in $folder as $USERNAME"
return 1
fi
@@ -448,6 +468,12 @@ else
if [ $config_ok -ne 0 ]; then
fail_unwritable_config_dir "$CONFIG_PATH"
fi
# The ingest/destination library (default /books) is user data and may be a
# bind mount owned by another uid; downloads fail with "Destination not
# writable" if the runtime user can't write there. Fix the top-level dir only
# (root mode) so we don't recursively chown a potentially huge library.
make_writable "${INGEST_DIR:-/books}" root
fi
# Always run Gunicorn (even when DEBUG=true) to ensure Socket.IO WebSocket
+4 -4
View File
@@ -22,25 +22,25 @@ dependencies = [
"qbittorrent-api",
"transmission-rpc",
"authlib>=1.7.2,<1.8",
"apprise>=1.10.0",
"apprise>=1.12.0",
]
[project.optional-dependencies]
browser = [
"pyvirtualdisplay",
"pyautogui",
"seleniumbase==4.48.4",
"seleniumbase==4.51.2",
"python-xlib",
]
[dependency-groups]
dev = [
"basedpyright>=1.39.3",
"basedpyright>=1.39.9",
"prek",
"pytest",
"pytest-cov",
"pytest-xdist>=3.8.0",
"ruff==0.15.12",
"ruff==0.15.22",
"vulture>=2.14",
]
+31
View File
@@ -2,6 +2,9 @@
<img src="src/frontend/public/logo.png" alt="Shelfmark" width="200">
> [!NOTE]
> This project is in a stable state as of May 2026 but is not under active maintenance.
Shelfmark is a self-hosted web interface for searching and requesting books and audiobooks across multiple sources. Bring your own sources, metadata providers, and download clients to build a single hub for your digital library. Supports multiple users with a built-in request system, so you can share your instance with others and let them browse and request books on their own.
Works great alongside the following library tools, with support for automatic imports:
@@ -103,6 +106,16 @@ Environment variables work for initial setup and Docker deployments. They serve
| `PUID` / `PGID` | Runtime user/group for the default root-startup flow (also supports legacy `UID`/`GID`) | `1000` / `1000` |
| `SEARCH_MODE` | `direct` or `universal` | `universal` |
| `USING_TOR` | Enable Tor routing (requires root startup) | `false` |
| `USING_WIREGUARD` | Enable WireGuard VPN egress with kill-switch (requires root startup) | `false` |
| `WIREGUARD_CONFIG` | Path to the mounted wg-quick config | `/config/wg0.conf` |
| `WIREGUARD_INTERFACE` | WireGuard interface name | `wg0` |
| `LAN_NETWORK` | Comma-separated CIDRs kept off the tunnel so the WebUI / internal clients stay reachable | `127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` |
| `WIREGUARD_ENFORCE_DNS` | Pin the resolver (via `WIREGUARD_DNS`, else the config's `DNS =`) so DNS can't silently fall back to an off-tunnel path. Designed for a trusted LAN resolver kept reachable via `LAN_NETWORK` (query leaves over the LAN; download still egresses via the tunnel) — it does **not** force queries through the tunnel. Docker's embedded resolver (`127.0.0.11`) is preserved when present so container-name resolution keeps working; pin its upstream via the container's `dns:` list. Fails closed if no resolver is available or `/etc/resolv.conf` is not writable. | `true` |
| `WIREGUARD_DNS` | Explicit resolver(s) to pin (comma/space separated). Use when the VPN's pushed DNS filters domains you need; point at a resolver reachable via the tunnel or an allowed LAN resolver. | _(unset; uses config `DNS =`)_ |
| `WIREGUARD_DISABLE_IPV6` | Strip IPv6 from the tunnel config (many container kernels lack the ip6tables `raw` table wg-quick needs) and remove IPv6 as a leak surface. | `true` |
| `WIREGUARD_ALLOW_IPV6_LEAK` | Escape hatch: continue even when an IPv6 kill-switch can't be installed AND IPv6 can't be disabled. Only set if the container has no IPv6 connectivity. | `false` |
| `WIREGUARD_ALLOW_WEBUI_OFFTUNNEL` | Opt-in off-tunnel WebUI reachability. Default (`false`) keeps the kill-switch strictly fail-closed: the only off-tunnel egress is loopback, the tunnel device and the LAN allowlist. Set `true` only if a **non-LAN** client (e.g. a public reverse proxy on another segment) must reach the WebUI; it permits app-server **replies** (`--sport FLASK_PORT`, conntrack REPLY) off-tunnel — server replies only, never client-initiated egress. LAN clients never need it (covered by `LAN_NETWORK`). | `false` |
| `WIREGUARD_STALE_AFTER` | Seconds since the last handshake before the healthcheck bounces the tunnel. | `180` |
See the full [Environment Variables Reference](docs/environment-variables.md) for all available options.
@@ -138,6 +151,24 @@ docker compose -f docker-compose.tor.yml up -d
- Timezone is auto-detected from Tor exit node
- Custom DNS/proxy settings are ignored when Tor is active
#### WireGuard VPN Routing
Optional WireGuard support to route all external egress through a VPN tunnel with a fail-closed kill-switch:
```bash
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.wireguard.yml
# place your wg-quick config where the compose mounts /config, as wg0.conf
docker compose -f docker-compose.wireguard.yml up -d
```
**Notes:**
- Requires root startup
- Requires `NET_ADMIN` and `NET_RAW` capabilities
- Mount a standard wg-quick config at `WIREGUARD_CONFIG` (default `/config/wg0.conf`)
- All non-LAN egress is forced through the tunnel; if the tunnel drops, external traffic **fails closed** while LAN ranges (WebUI, Prowlarr, qBittorrent) stay reachable
- IPv4 and IPv6 both fail closed. On kernels without a usable `ip6tables`, disable IPv6 for the container (`sysctls: net.ipv6.conf.all.disable_ipv6=1`, as in the compose example) or the container refuses to start rather than risk an IPv6 leak
- A supervised healthcheck bounces the tunnel if the handshake goes stale, and refreshes the endpoint allow rules so a roaming/rotated peer endpoint can reconnect
- Mutually exclusive with `USING_TOR`
- **DNS trust:** `WIREGUARD_DNS` must be a resolver you trust on a trusted network segment. When it is a LAN resolver (kept reachable off-tunnel by `LAN_NETWORK`), the query to that resolver leaves as plaintext UDP/53 on the LAN — the resolver is responsible for encrypting upstream. Two resolver paths exist: (1) when Docker's embedded resolver (`127.0.0.11`) is present it is **preserved** so container names (Prowlarr, qBittorrent) resolve — you MUST pin its upstream to a trusted resolver via the container's compose `dns:` list, since `WIREGUARD_DNS` cannot repoint the embedded resolver from inside the container; (2) otherwise `WIREGUARD_DNS`/the config `DNS =` line is written to `/etc/resolv.conf`. Setting `WIREGUARD_ENFORCE_DNS=false` is a **foot-gun**: with no embedded resolver present the container then uses its inherited resolver, which forwards to the Docker daemon's upstream **off-tunnel**, leaking your DNS. Leave enforcement on unless you have pinned the resolver another way.
### Lite
A lighter image without the built-in browser automation. Ideal for:
+111
View File
@@ -238,6 +238,113 @@ def _generate_bootstrap_env_docs() -> list[str]:
return lines
def _generate_egress_env_docs() -> list[str]:
"""Generate documentation for VPN/Tor egress environment variables.
These are startup-only variables consumed by entrypoint.sh / wireguard.sh
(before and outside the settings registry) to select and configure the
transparent-egress kill-switch. `USING_TOR` has a registry-backed entry
under Network and is cross-referenced rather than repeated here so the two
mutually exclusive egress modes are discoverable side by side without
emitting a duplicate `#### USING_TOR` anchor.
"""
egress_vars = [
{
"name": "USING_WIREGUARD",
"description": "Route all traffic through a WireGuard VPN tunnel with a fail-closed iptables kill-switch (non-tunnel egress is dropped). Requires root startup and NET_ADMIN (plus NET_RAW). Mutually exclusive with USING_TOR.",
"type": "boolean",
"default": "false",
},
{
"name": "WIREGUARD_CONFIG",
"description": "Path to the mounted wg-quick configuration file.",
"type": "string (path)",
"default": "/config/wg0.conf",
},
{
"name": "WIREGUARD_INTERFACE",
"description": "WireGuard interface name brought up by wg-quick.",
"type": "string",
"default": "wg0",
},
{
"name": "LAN_NETWORK",
"description": "Comma-separated CIDRs kept off the tunnel so the WebUI and internal download clients (Prowlarr, qBittorrent) stay reachable.",
"type": "string (comma-separated)",
"default": "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16",
},
{
"name": "WIREGUARD_ENFORCE_DNS",
"description": "Pin the container's resolver so DNS cannot silently fall back to an off-tunnel path. The resolver used is WIREGUARD_DNS if set, else the tunnel config's DNS = line. This does NOT force queries through the tunnel: it is designed for a trusted LAN resolver kept reachable off-tunnel via LAN_NETWORK (the query leaves over the LAN; the resolver encrypts upstream while the download still egresses via the tunnel). Special case: when Docker's embedded resolver (nameserver 127.0.0.11) is present, it is PRESERVED so container-name resolution (e.g. prowlarr, qbittorrent) keeps working, and the embedded resolver's upstream must be pinned via the container's compose dns: list. Fails closed (refuses to start) only when no embedded resolver is present AND no resolver is defined, or /etc/resolv.conf is not writable.",
"type": "boolean",
"default": "true",
},
{
"name": "WIREGUARD_DNS",
"description": "Explicit resolver(s) (comma/space separated) to pin when WIREGUARD_ENFORCE_DNS is true and Docker's embedded resolver is NOT in use. Use when the VPN's pushed DNS filters domains you need; point it at a resolver reachable via the tunnel or an allowed LAN resolver. NOTE: when the embedded resolver (127.0.0.11) is present it is preserved and this value cannot repoint its upstream from inside the container — set the container's compose dns: list to the trusted resolver instead.",
"type": "string (comma-separated)",
"default": "unset (uses config DNS = line)",
},
{
"name": "WIREGUARD_DISABLE_IPV6",
"description": "Strip IPv6 Address/AllowedIPs/DNS from the tunnel config before wg-quick (many container kernels lack the ip6tables raw table wg-quick needs) and remove IPv6 as a leak surface.",
"type": "boolean",
"default": "true",
},
{
"name": "WIREGUARD_ALLOW_IPV6_LEAK",
"description": "Escape hatch: continue startup even when an IPv6 kill-switch cannot be installed AND IPv6 cannot be disabled. Only set when the container has no IPv6 connectivity, as IPv6 egress may otherwise bypass the tunnel.",
"type": "boolean",
"default": "false",
},
{
"name": "WIREGUARD_ALLOW_WEBUI_OFFTUNNEL",
"description": "When false (default) the kill-switch is strictly fail-closed: the only off-tunnel egress permitted is loopback, the tunnel device and the LAN allowlist. Set true only if a NON-LAN client (e.g. a public reverse proxy on a different segment) must reach the WebUI; it permits app-server REPLY packets (--sport FLASK_PORT, conntrack REPLY) to leave off-tunnel. Server replies only, never client-initiated egress, so it cannot leak outbound browsing/downloads or the real IP for outbound requests, but it is still an off-tunnel path while the tunnel is down, hence opt-in. LAN WebUI clients never need it (covered by LAN_NETWORK).",
"type": "boolean",
"default": "false",
},
{
"name": "WIREGUARD_STALE_AFTER",
"description": "Seconds since the last WireGuard handshake before the healthcheck bounces the tunnel.",
"type": "number",
"default": "180",
},
]
lines = [
"## Egress / VPN Routing",
"",
"These startup-only variables are consumed by `entrypoint.sh` / `wireguard.sh` to select and configure the WireGuard transparent-egress kill-switch. `USING_WIREGUARD` and [`USING_TOR`](#using_tor) (documented under Network) are mutually exclusive; both require root startup.",
"",
"| Variable | Description | Type | Default |",
"|----------|-------------|------|---------|",
]
lines.extend(
f"| `{var['name']}` | {var['description']} | {var['type']} | `{var['default']}` |"
for var in egress_vars
)
lines.append("")
lines.append("<details>")
lines.append("<summary>Detailed descriptions</summary>")
lines.append("")
for var in egress_vars:
lines.append(f"#### `{var['name']}`")
lines.append("")
lines.append(var["description"])
lines.append("")
lines.append(f"- **Type:** {var['type']}")
lines.append(f"- **Default:** `{var['default']}`")
lines.append("")
lines.append("</details>")
lines.append("")
return lines
def generate_env_docs() -> str:
"""Generate markdown documentation for all environment variables."""
# Import settings modules to ensure all settings are registered
@@ -282,6 +389,7 @@ def generate_env_docs() -> str:
# Generate TOC
toc_entries = [
"- [Bootstrap Configuration](#bootstrap-configuration)",
"- [Egress / VPN Routing](#egress--vpn-routing)",
]
# Ungrouped tabs first
@@ -307,6 +415,9 @@ def generate_env_docs() -> str:
# Add bootstrap environment variables documentation
lines.extend(_generate_bootstrap_env_docs())
# Add egress / VPN routing (startup-only, shell-driven) documentation
lines.extend(_generate_egress_env_docs())
# Generate documentation for ungrouped tabs
for tab in grouped_tabs.get(None, []):
lines.extend(_generate_tab_docs(tab))
+39 -1
View File
@@ -939,7 +939,17 @@ def _get_via_subprocess(url: str, retry: int, cancel_flag: Event | None = None)
result_path = (
Path(tempfile.gettempdir()) / f"shelfmark-bypass-{os.getpid()}-{time.time_ns()}.json"
)
payload = {"url": url, "retry": retry, "result_path": str(result_path)}
# DNS provider state lives only in the parent's memory (no disk persistence), so the
# freshly spawned helper would otherwise pre-resolve AA hostnames against the system
# resolver - which may be blocked or hijacked by the user's ISP. Pass the parent's
# active DNS config so the helper mirrors it (e.g. DoH) when building Chrome's host
# resolver rules.
payload = {
"url": url,
"retry": retry,
"result_path": str(result_path),
"dns_config": network.get_dns_config(),
}
env_vars = os.environ.copy()
env_vars[_BYPASS_CHILD_ENV] = "1"
env_vars = _prepare_child_browser_env(env_vars)
@@ -1278,6 +1288,30 @@ def get_bypassed_page(
return response_html
def _apply_parent_dns_config(dns_config: dict[str, Any]) -> None:
"""Mirror the parent process's active DNS provider in this helper subprocess.
DNS state is in-memory only, so a fresh helper defaults to system DNS and would
pre-resolve AA hostnames (for Chrome's --host-resolver-rules) against a resolver
that may be blocked/hijacked. Re-applying the parent's provider keeps the helper on
the same DoH/custom resolver the parent already validated.
"""
provider = str(dns_config.get("provider") or "").strip().lower()
# "auto" means the parent has not rotated off system DNS yet, so the helper's own
# default initialization already matches it - nothing to override.
if not provider or provider == "auto":
return
manual_servers = dns_config.get("servers") if provider == "manual" else None
try:
network.set_dns_provider(
provider,
manual_servers,
use_doh=bool(dns_config.get("doh_enabled")),
)
except (OSError, RuntimeError, ValueError) as exc:
logger.warning("Could not apply parent DNS config (%s): %s", provider, exc)
def _run_child_process() -> int:
"""CLI entrypoint used by the Docker helper subprocess."""
request = json.loads(sys.stdin.read() or "{}")
@@ -1287,6 +1321,10 @@ def _run_child_process() -> int:
request.get("retry"), _coerce_positive_int(app_config.MAX_RETRY, 10)
)
dns_config = request.get("dns_config")
if isinstance(dns_config, dict):
_apply_parent_dns_config(dns_config)
try:
html = get(url, retry=retry)
payload = {
+2 -1
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
import hashlib
from typing import Any
from shelfmark.core.config import config
@@ -23,7 +24,7 @@ _BOOKLORE_OPTIONS_CACHE: dict[str, Any] = {
def _get_booklore_cache_key(base_url: str, username: str, password: str) -> str:
return f"{base_url}|{username}|{hash(password)}"
return f"{base_url}|{username}|{hashlib.sha256(password.encode()).hexdigest()}"
def _get_booklore_select_options(
+19 -1
View File
@@ -115,7 +115,7 @@ def check_oidc_connection(
response.raise_for_status()
document = response.json()
required_fields = ["issuer", "authorization_endpoint", "token_endpoint"]
required_fields = ["issuer", "authorization_endpoint", "token_endpoint", "jwks_uri"]
missing_fields = [field for field in required_fields if field not in document]
if missing_fields:
return {
@@ -123,6 +123,24 @@ def check_oidc_connection(
"message": f"Discovery document missing fields: {', '.join(missing_fields)}",
}
# Logins verify the ID token against the provider's JWKS, so an empty key
# set (e.g. an Authentik provider with no Signing Key selected) means every
# login will fail even though discovery looks healthy.
jwks_uri = str(document["jwks_uri"])
jwks_response = requests.get(jwks_uri, timeout=10, verify=get_ssl_verify(jwks_uri))
jwks_response.raise_for_status()
jwks_document = jwks_response.json()
jwks_keys = jwks_document.get("keys") if isinstance(jwks_document, dict) else None
if not jwks_keys:
return {
"success": False,
"message": (
"Discovery document is valid, but the provider returned no token "
"signing keys (empty JWKS), so logins will fail. If you use "
"Authentik, select a Signing Key in the provider settings."
),
}
return {"success": True, "message": f"Connected to {document['issuer']}"}
except Exception as exc:
logger.exception("OIDC connection test failed")
+68
View File
@@ -36,6 +36,9 @@ from shelfmark.core.settings_registry import (
register_settings,
)
_DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_DEFAULT = 60
_DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_MAX = 3600
def _on_save_advanced(values: dict[str, Any]) -> dict[str, Any]:
"""Validate advanced settings before persisting."""
@@ -43,6 +46,40 @@ def _on_save_advanced(values: dict[str, Any]) -> dict[str, Any]:
logger = setup_logger(__name__)
timeout_key = "DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT"
if timeout_key in values:
raw_timeout = values.get(timeout_key)
if isinstance(raw_timeout, bool):
return {
"error": True,
"message": "Completed Path Wait must be a number of seconds",
"values": values,
}
if raw_timeout is None:
return {
"error": True,
"message": "Completed Path Wait must be a number of seconds",
"values": values,
}
try:
timeout_seconds = int(raw_timeout)
except TypeError, ValueError:
return {
"error": True,
"message": "Completed Path Wait must be a number of seconds",
"values": values,
}
if timeout_seconds < 0 or timeout_seconds > _DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_MAX:
return {
"error": True,
"message": (
"Completed Path Wait must be between 0 and "
f"{_DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_MAX} seconds"
),
"values": values,
}
values[timeout_key] = timeout_seconds
mappings = values.get("PROWLARR_REMOTE_PATH_MAPPINGS")
if mappings is None:
return {"error": False, "values": values}
@@ -453,6 +490,14 @@ def search_mode_settings() -> list[SettingsField]:
show_when={"field": "SEARCH_MODE", "value": "universal"},
user_overridable=True,
),
CheckboxField(
key="FORCE_COMBINED_SEARCH",
label="Always Use Combined Search",
description="Force combined search whenever it's available. Locks the combined toggle on.",
default=False,
show_when={"field": "SEARCH_MODE", "value": "universal"},
user_overridable=True,
),
HeadingField(
key="universal_mode_heading",
title="Universal Mode Settings",
@@ -1440,6 +1485,17 @@ def download_source_settings() -> list[SettingsField]:
),
default=False,
),
CheckboxField(
key="DIRECT_DOWNLOAD_LANGUAGE_FROM_PATH",
label="Detect Language From Distant Path",
description=(
"When language metadata is missing or unknown, parse the distant path "
"(file path shown in search results) for language tags like [BD FR] or [En]. "
"Also enables local language filtering so lgli files without AA language "
"metadata are not excluded before the distant path can be checked."
),
default=False,
),
PasswordField(
key="AA_DONATOR_KEY",
label="Account Donator Key",
@@ -1761,6 +1817,18 @@ def advanced_settings() -> list[SettingsField]:
title="Remote Path Mappings",
description="Map download client paths to paths inside Shelfmark. Needed when volume mounts differ between containers.",
),
NumberField(
key="DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT",
label="Completed Path Wait (seconds)",
description=(
"How long to wait after a torrent or usenet client reports completion "
"for the completed file path to become visible to Shelfmark. Increase "
"this for seedbox or remote-sync workflows."
),
default=_DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_DEFAULT,
min_value=0,
max_value=_DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT_MAX,
),
TableField(
key="PROWLARR_REMOTE_PATH_MAPPINGS",
label="Path Mappings",
+6
View File
@@ -82,6 +82,7 @@ _SEARCH_PREFERENCE_VALIDATABLE_KEYS = {
"DEFAULT_RELEASE_SOURCE",
"DEFAULT_RELEASE_SOURCE_AUDIOBOOK",
"SHOW_COMBINED_SELECTOR",
"FORCE_COMBINED_SEARCH",
*_SEARCH_PREFERENCE_PROVIDER_KEYS,
}
@@ -223,6 +224,11 @@ def validate_search_preference_value(key: str, value: Any) -> tuple[Any, str | N
return value, None
return bool(value), None
if key == "FORCE_COMBINED_SEARCH":
if isinstance(value, bool):
return value, None
return bool(value), None
return value, None
+3
View File
@@ -108,6 +108,9 @@ class DownloadTask:
retry_expected_hash: str | None = None # Optional torrent hash used to match client downloads
retry_ratio_limit: float | None = None # Optional post-download seeding ratio
retry_seeding_time_limit_minutes: int | None = None # Optional post-download seeding time limit
retry_source_context: dict[str, Any] = field(
default_factory=dict
) # Source-private context for retry/re-resolution
can_retry_without_staged_source: bool = (
True # Whether the source can restart without a preserved staged file
)
+1 -2
View File
@@ -91,8 +91,7 @@ PAD_NUMBERS_PATTERN = re.compile(r"\d+")
def natural_sort_key(path: str | Path) -> str:
"""Generate a sort key with padded numbers for natural sorting."""
filename = Path(path).name.lower()
return PAD_NUMBERS_PATTERN.sub(lambda m: m.group().zfill(9), filename)
return PAD_NUMBERS_PATTERN.sub(lambda m: m.group().zfill(9), str(path).lower())
def assign_part_numbers(
+42
View File
@@ -393,6 +393,41 @@ def _plugin_label(plugin: object, fallback_scheme: str) -> str:
return " ".join(parts)
def _apprise_proxy_env() -> dict[str, str]:
"""Build proxy env vars from app config so Apprise respects the proxy setting."""
import os
from shelfmark.core.config import config as _cfg
mode = str(_cfg.get("PROXY_MODE", "") or "").lower()
env: dict[str, str] = {}
if mode == "http":
http = str(_cfg.get("HTTP_PROXY", "") or "").strip()
https = str(_cfg.get("HTTPS_PROXY", "") or "").strip() or http
if http:
env["HTTP_PROXY"] = http
env["http_proxy"] = http
if https:
env["HTTPS_PROXY"] = https
env["https_proxy"] = https
elif mode == "socks5":
socks = str(_cfg.get("SOCKS5_PROXY", "") or "").strip()
if socks:
env["HTTP_PROXY"] = socks
env["http_proxy"] = socks
env["HTTPS_PROXY"] = socks
env["https_proxy"] = socks
no_proxy = str(_cfg.get("NO_PROXY", "") or "").strip()
if no_proxy and env:
env["NO_PROXY"] = no_proxy
env["no_proxy"] = no_proxy
# Don't override if the user already set these in the environment directly
return {k: v for k, v in env.items() if not os.environ.get(k)}
def _dispatch_to_apprise(
urls: Iterable[str],
*,
@@ -400,6 +435,8 @@ def _dispatch_to_apprise(
body: str,
notify_type: object,
) -> dict[str, Any]:
import os
normalized_urls = _normalize_urls(list(urls))
url_schemes = _extract_url_schemes(normalized_urls)
if not normalized_urls:
@@ -408,6 +445,11 @@ def _dispatch_to_apprise(
if apprise is None:
return {"success": False, "message": "Apprise is not installed"}
proxy_env = _apprise_proxy_env()
if proxy_env:
logger.debug("Applying proxy env for Apprise dispatch: %s", list(proxy_env.keys()))
os.environ.update(proxy_env)
valid_urls = 0
invalid_urls = 0
delivered_urls = 0
+33
View File
@@ -33,6 +33,11 @@ logger = setup_logger(__name__)
oauth = OAuth()
_RETURN_TO_SESSION_KEY = "oidc_return_to"
_OIDC_CLIENT_ERRORS = (OAuthError, OSError, RuntimeError, TypeError, ValueError)
_EMPTY_JWKS_MESSAGE = (
"Authentication failed: the identity provider returned no token signing keys "
"(empty JWKS). If you use Authentik, select a Signing Key in the provider "
"settings and try again."
)
class _ClaimsMappingLike(Protocol):
@@ -121,6 +126,17 @@ def _normalize_return_to(raw_return_to: object) -> str | None:
return urlunsplit(("", "", path, parsed.query, parsed.fragment))
def _idp_jwks_has_no_keys(client: Any) -> bool:
"""Return True when the IdP's JWKS document verifiably contains no signing keys."""
try:
jwk_set = client.fetch_jwk_set(force=True)
except (*_OIDC_CLIENT_ERRORS, KeyError):
return False
if not isinstance(jwk_set, Mapping):
return False
return not jwk_set.get("keys")
def _get_pending_return_to(*, clear: bool = False) -> str | None:
"""Read the pending post-login target from the session."""
raw_return_to = (
@@ -274,6 +290,17 @@ def register_oidc_routes(app: Flask, user_db: UserDB) -> None:
return redirect(
_login_error_url(f"OIDC token claim validation failed: {claim_name}")
)
except KeyError, ValueError:
# An IdP serving an empty JWKS document (e.g. an Authentik provider
# with no Signing Key selected) surfaces as KeyError('keys') while
# importing the key set. Test Connection only validates discovery,
# so this is the first place the misconfiguration becomes visible.
if _idp_jwks_has_no_keys(client):
logger.exception(
"OIDC callback failed: the IdP JWKS document contains no signing keys"
)
return redirect(_login_error_url(_EMPTY_JWKS_MESSAGE))
raise
claims = _normalize_claims(token.get("userinfo"))
# If userinfo is missing or claims are too sparse, request it explicitly.
@@ -306,6 +333,12 @@ def register_oidc_routes(app: Flask, user_db: UserDB) -> None:
is_admin = admin_group in groups
allow_email_link = bool(user_info.get("email")) and _is_email_verified(claims)
if user_info.get("email") and not allow_email_link:
logger.debug(
"OIDC email %s is not marked verified by the IdP; skipping "
"email-based account linking",
user_info["email"],
)
user = provision_oidc_user(
user_db,
user_info,
+7
View File
@@ -52,6 +52,13 @@ def normalize_http_url(
if scheme:
normalized = f"{scheme}://{normalized}"
# Strip query string and fragment — mirrors are used as base URLs for
# constructing search requests; params/fragments on the configured URL
# produce malformed URLs when paths are appended (issue #999).
parsed = urlparse(normalized)
if parsed.query or parsed.fragment:
normalized = parsed._replace(query="", fragment="").geturl()
if strip_trailing_slash:
normalized = normalized.rstrip("/")
+146 -26
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import errno
import math
import shutil
import time
from abc import ABC, abstractmethod
@@ -55,6 +56,19 @@ SECONDS_PER_HOUR = 3600
# How long to wait for completed files to appear (seconds)
COMPLETED_PATH_RETRY_INTERVAL = 5
COMPLETED_PATH_MAX_ATTEMPTS = 12 # 12 attempts * 5s = 60s grace period
COMPLETED_PATH_TIMEOUT_SETTING = "DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT"
COMPLETED_PATH_TIMEOUT_MAX_SECONDS = 3600
_RETRYABLE_COMPLETED_PATH_ERRNOS = frozenset(
code
for code in (
errno.ENOENT,
getattr(errno, "ESTALE", None),
getattr(errno, "EAGAIN", None),
getattr(errno, "EBUSY", None),
getattr(errno, "ETIMEDOUT", None),
)
if code is not None
)
@dataclass(frozen=True)
@@ -69,6 +83,39 @@ class DownloadRequest:
ratio_limit: float | None = None
@dataclass(frozen=True)
class _CompletedPathResolution:
path: Path | None
error: str | None
retryable: bool
def _coerce_completed_path_timeout_seconds(value: object, default: float) -> float:
if isinstance(value, bool) or value is None:
return default
if isinstance(value, (int, float)):
parsed = float(value)
elif isinstance(value, str):
try:
parsed = float(value.strip())
except ValueError:
return default
else:
return default
if not math.isfinite(parsed) or parsed < 0:
return default
return min(parsed, float(COMPLETED_PATH_TIMEOUT_MAX_SECONDS))
def _is_retryable_completed_path_probe(error: OSError | None) -> bool:
return error is not None and error.errno in _RETRYABLE_COMPLETED_PATH_ERRNOS
def _path_needs_mapping(path: str) -> bool:
return (len(path) >= WINDOWS_DRIVE_PREFIX_LENGTH and path[1] == ":") or "\\" in path
def _diagnose_path_issue(path: str) -> str:
"""Analyze a path and return diagnostic hints for common issues.
@@ -167,6 +214,23 @@ class ExternalClientHandler(DownloadHandler, ABC):
"""Maximum attempts when waiting for completed files."""
return COMPLETED_PATH_MAX_ATTEMPTS
def _completed_path_timeout_seconds(self) -> float:
"""Total time to wait for completed files to appear on disk."""
fallback = self._completed_path_retry_interval() * self._completed_path_max_attempts()
configured = config.get(COMPLETED_PATH_TIMEOUT_SETTING, fallback)
return _coerce_completed_path_timeout_seconds(configured, fallback)
def _refresh_download_request_after_add_failure(
self,
*,
task: DownloadTask,
request: DownloadRequest,
error: Exception,
status_callback: Callable[[str, str | None], None],
) -> DownloadRequest | None:
"""Give source handlers one chance to refresh stale resolved download data."""
return None
def _get_category_for_task(self, client: DownloadClient, task: DownloadTask) -> str | None:
"""Get audiobook category if configured and applicable, else None for default."""
if not is_audiobook(task.content_type):
@@ -387,6 +451,21 @@ class ExternalClientHandler(DownloadHandler, ABC):
log_details: bool,
) -> tuple[Path | None, str | None]:
"""Resolve and validate the completed download path once."""
result = self._resolve_download_path_once_detailed(
client,
download_id,
log_details=log_details,
)
return result.path, result.error
def _resolve_download_path_once_detailed(
self,
client: DownloadClient,
download_id: str,
*,
log_details: bool,
) -> _CompletedPathResolution:
"""Resolve and validate a completed path, including retryability."""
try:
raw_path = client.get_download_path(download_id)
except Exception as e:
@@ -402,7 +481,7 @@ class ExternalClientHandler(DownloadHandler, ABC):
logger.debug(
"Failed to resolve download path for %s %s: %s", client.name, download_id, e
)
return None, message
return _CompletedPathResolution(None, message, retryable=False)
if not raw_path:
message = (
@@ -417,7 +496,7 @@ class ExternalClientHandler(DownloadHandler, ABC):
logger.debug(
"Download client returned empty path for %s %s", client.name, download_id
)
return None, message
return _CompletedPathResolution(None, message, retryable=False)
from shelfmark.core.path_mappings import (
get_client_host_identifier,
@@ -457,7 +536,7 @@ class ExternalClientHandler(DownloadHandler, ABC):
logger.error(failure_log, *failure_args)
else:
logger.debug(failure_log, *failure_args)
return None, message
return _CompletedPathResolution(None, message, retryable=False)
remapped_exists, remapped_error = _probe_completed_path(remapped)
@@ -480,7 +559,7 @@ class ExternalClientHandler(DownloadHandler, ABC):
source_path_obj,
remapped,
)
return remapped, None
return _CompletedPathResolution(remapped, None, retryable=False)
message = (
f"Remapped path '{remapped}' does not exist. "
@@ -499,7 +578,11 @@ class ExternalClientHandler(DownloadHandler, ABC):
logger.error(failure_log, *failure_args)
else:
logger.debug(failure_log, *failure_args)
return None, message
return _CompletedPathResolution(
None,
message,
retryable=_is_retryable_completed_path_probe(remapped_error),
)
source_exists, source_error = _probe_completed_path(source_path_obj)
@@ -522,7 +605,7 @@ class ExternalClientHandler(DownloadHandler, ABC):
download_id,
source_path_obj,
)
return source_path_obj, None
return _CompletedPathResolution(source_path_obj, None, retryable=False)
hint = _diagnose_path_issue(raw_path)
if mappings:
@@ -555,7 +638,12 @@ class ExternalClientHandler(DownloadHandler, ABC):
logger.error(failure_log, *failure_args)
else:
logger.debug(failure_log, *failure_args)
return None, message
return _CompletedPathResolution(
None,
message,
retryable=not _path_needs_mapping(raw_path)
and _is_retryable_completed_path_probe(source_error),
)
def _wait_for_completed_path(
self,
@@ -567,23 +655,37 @@ class ExternalClientHandler(DownloadHandler, ABC):
) -> tuple[Path | None, str | None]:
"""Wait briefly for completed files to appear on disk."""
last_error: str | None = None
max_attempts = self._completed_path_max_attempts()
retry_interval = self._completed_path_retry_interval()
timeout_seconds = self._completed_path_timeout_seconds()
if retry_interval <= 0 or timeout_seconds <= 0:
max_attempts = 1
else:
max_attempts = int(math.ceil(timeout_seconds / retry_interval)) + 1
for attempt in range(1, max_attempts + 1):
if cancel_flag and cancel_flag.is_set():
return None, last_error
log_details = attempt == max_attempts
resolved_path, error = self._resolve_download_path_once(
result = self._resolve_download_path_once_detailed(
client,
download_id,
log_details=log_details,
)
if resolved_path:
return resolved_path, None
if result.path:
return result.path, None
last_error = error
last_error = result.error
if not result.retryable:
if not log_details:
logger.error(
"Completed path resolution is not retryable for %s (%s): %s",
client.name,
download_id,
last_error,
)
return None, last_error
if attempt < max_attempts:
status_callback("locating", "Waiting for completed files...")
@@ -700,20 +802,38 @@ class ExternalClientHandler(DownloadHandler, ABC):
status_callback("downloading", "Resuming existing download")
else:
# No existing download - add new
status_callback("resolving", f"Sending to {client.name}")
try:
download_id = client.add_download(
url=request.url,
name=request.release_name,
category=category,
expected_hash=request.expected_hash,
seeding_time_limit=request.seeding_time_limit,
ratio_limit=request.ratio_limit,
)
except Exception as e:
logger.exception("Failed to add to %s", client.name)
status_callback("error", f"Failed to add to {client.name}: {e}")
return None
refresh_attempted = False
while True:
status_callback("resolving", f"Sending to {client.name}")
try:
download_id = client.add_download(
url=request.url,
name=request.release_name,
category=category,
expected_hash=request.expected_hash,
seeding_time_limit=request.seeding_time_limit,
ratio_limit=request.ratio_limit,
)
except Exception as e:
if not refresh_attempted:
refresh_attempted = True
refreshed_request = self._refresh_download_request_after_add_failure(
task=task,
request=request,
error=e,
status_callback=status_callback,
)
if (
refreshed_request is not None
and refreshed_request.protocol == request.protocol
):
request = refreshed_request
continue
logger.exception("Failed to add to %s", client.name)
status_callback("error", f"Failed to add to {client.name}: {e}")
return None
break
logger.info(
"Added to %s: %s for '%s'", client.name, download_id, request.release_name
+4 -1
View File
@@ -277,7 +277,10 @@ class DelugeClient(DownloadClient):
torrent_info = extract_torrent_info(url, expected_hash=expected_hash)
if not torrent_info.is_magnet and not torrent_info.torrent_data:
_raise_runtime_error("Failed to fetch torrent file")
message = "Failed to fetch torrent file"
if torrent_info.fetch_error:
message = f"{message}: {torrent_info.fetch_error}"
_raise_runtime_error(message)
options: dict[str, Any] = {}
if self._download_dir:
+57 -4
View File
@@ -258,7 +258,7 @@ class QBittorrentClient(DownloadClient):
self._tags = _normalize_tags(config.get("QBITTORRENT_TAG", []))
def _get_torrents_info(
self, torrent_hash: str | None = None
self, torrent_hash: str | None = None, category: str | None = None
) -> tuple[list[SimpleNamespace], str | None]:
"""Get torrent info using GET.
@@ -267,6 +267,7 @@ class QBittorrentClient(DownloadClient):
- Keep "API/auth/connect" errors distinct from "torrent missing".
- If a hash-specific query returns empty, fall back to listing by category
and matching locally.
- Without a hash, `category` narrows the listing to that category.
Returns:
(torrents, error_message)
@@ -301,6 +302,8 @@ class QBittorrentClient(DownloadClient):
primary_params: dict[str, str] = {}
if torrent_hash:
primary_params["hashes"] = torrent_hash
elif category:
primary_params["category"] = category
response = do_request(primary_params)
torrents, error = parse_response(response, request_params=primary_params)
@@ -358,6 +361,44 @@ class QBittorrentClient(DownloadClient):
else:
return torrents, None
def _list_category_hashes(self, category: str | None) -> set[str] | None:
"""Snapshot the hashes qBittorrent currently reports for a category."""
torrents, error = self._get_torrents_info(category=category)
if error:
logger.debug("Could not snapshot qBittorrent torrents: %s", error)
return None
return {str(torrent.hash).lower() for torrent in torrents if getattr(torrent, "hash", None)}
def _discover_added_torrent_hash(
self,
name: str,
category: str | None,
known_hashes: set[str] | None,
) -> str | None:
"""Recover the hash of a torrent that was added without a known info_hash.
A `known_hashes` of None means the pre-add snapshot failed, so only a
torrent matching the requested rename can identify the new arrival.
"""
for _ in range(20):
torrents, error = self._get_torrents_info(category=category)
if error:
logger.debug("qBittorrent hash discovery: %s", error)
else:
new_torrents = [
torrent
for torrent in torrents
if getattr(torrent, "hash", None)
and (known_hashes is None or str(torrent.hash).lower() not in known_hashes)
]
for torrent in new_torrents:
if getattr(torrent, "name", None) == name:
return str(torrent.hash).lower()
if known_hashes is not None and len(new_torrents) == 1:
return str(new_torrents[0].hash).lower()
time.sleep(0.5)
return None
@staticmethod
def is_configured() -> bool:
"""Check if qBittorrent is configured and selected as the torrent client."""
@@ -425,6 +466,10 @@ class QBittorrentClient(DownloadClient):
expected_hash = torrent_info.info_hash
torrent_data = torrent_info.torrent_data
known_hashes: set[str] | None = None
if not expected_hash:
known_hashes = self._list_category_hashes(category)
# Per-torrent seeding limits from indexer
seeding_time_limit_value = kwargs.get("seeding_time_limit")
seeding_time_limit = coerce_optional_int(seeding_time_limit_value)
@@ -459,12 +504,20 @@ class QBittorrentClient(DownloadClient):
result_text = _normalize_add_result(result)
logger.debug("qBittorrent add result: %s", result_text)
if not expected_hash:
_raise_runtime_error("Could not determine torrent hash from URL")
if _is_explicit_add_failure(result):
_raise_runtime_error(f"Failed to add torrent: {result_text}")
if not expected_hash:
# qBittorrent fetches .torrent URLs itself, so the add can succeed
# even when no hash could be extracted up front. Recover it by
# watching for the new torrent to appear.
expected_hash = self._discover_added_torrent_hash(name, category, known_hashes)
if not expected_hash:
message = "Could not determine torrent hash from URL"
if torrent_info.fetch_error:
message = f"{message} (torrent file fetch failed: {torrent_info.fetch_error})"
_raise_runtime_error(message)
# Some qBittorrent-compatible clients return HTTP 200 with an empty body
# instead of qBittorrent's literal "Ok." response. Prefer verifying that
# the torrent becomes visible over trusting the response body alone.
+70 -2
View File
@@ -4,6 +4,7 @@ Uses xmlrpc to communicate with rTorrent's RPC interface.
"""
import ssl
import time
import xmlrpc.client as stdlib_xmlrpc_client
from typing import Any, NoReturn, Protocol, cast
from urllib.parse import urlparse
@@ -115,6 +116,7 @@ class RTorrentClient(DownloadClient):
self._rpc = _create_rtorrent_server_proxy(self._base_url)
self._download_dir = config_text(config.get("RTORRENT_DOWNLOAD_DIR", ""))
self._label = config_text(config.get("RTORRENT_LABEL", ""))
self._audiobook_label = config_text(config.get("RTORRENT_AUDIOBOOK_LABEL", ""))
@staticmethod
def is_configured() -> bool:
@@ -159,9 +161,17 @@ class RTorrentClient(DownloadClient):
try:
torrent_info = extract_torrent_info(url, expected_hash=expected_hash)
known_hashes: set[str] | None = None
if not (torrent_info.info_hash or expected_hash):
known_hashes = self._list_torrent_hashes()
commands = []
label = category or self._label
is_audiobook = kwargs.get("content_type") == "audiobook"
default_label = (
self._audiobook_label if is_audiobook and self._audiobook_label else self._label
)
label = category or default_label
if label:
logger.debug("Setting rTorrent label: %s", label)
commands.append(f"d.custom1.set={label}")
@@ -191,7 +201,15 @@ class RTorrentClient(DownloadClient):
torrent_hash = torrent_info.info_hash or expected_hash
if not torrent_hash:
_raise_runtime_error("Could not determine torrent hash from URL")
# rTorrent fetches .torrent URLs itself, so the add can succeed
# even when no hash could be extracted up front. Recover it by
# watching for the new download to appear.
torrent_hash = self._discover_added_torrent_hash(name, label, known_hashes)
if not torrent_hash:
message = "Could not determine torrent hash from URL"
if torrent_info.fetch_error:
message = f"{message} (torrent file fetch failed: {torrent_info.fetch_error})"
_raise_runtime_error(message)
logger.debug("Added torrent to rTorrent: %s", torrent_hash)
@@ -382,6 +400,56 @@ class RTorrentClient(DownloadClient):
except _RTORRENT_CLIENT_ERRORS:
return "/downloads"
def _list_torrent_hashes(self) -> set[str] | None:
"""Snapshot the hashes rTorrent currently reports."""
try:
all_torrents = self._rpc.d.multicall2("", "", "d.hash=")
except _RTORRENT_CLIENT_ERRORS as e:
logger.debug("Could not snapshot rTorrent downloads: %s", e)
return None
return {str(row[0]).lower() for row in all_torrents if row and row[0]}
def _discover_added_torrent_hash(
self,
name: str,
label: str,
known_hashes: set[str] | None,
) -> str | None:
"""Recover the hash of a torrent that was added without a known info_hash.
rTorrent fetches .torrent URLs itself, so the add can succeed even when
no hash could be extracted up front. A `known_hashes` of None means the
pre-add snapshot failed, so only an exact name match can identify the
new arrival.
"""
for _ in range(20):
try:
all_torrents = self._rpc.d.multicall2("", "", "d.hash=", "d.name=", "d.custom1=")
except _RTORRENT_CLIENT_ERRORS as e:
logger.debug("rTorrent hash discovery: %s", e)
else:
new_torrents = [
row
for row in all_torrents
if row
and row[0]
and (known_hashes is None or str(row[0]).lower() not in known_hashes)
]
# The label set at add time distinguishes concurrent arrivals,
# but rTorrent may not have applied it yet, so it only ever
# narrows a non-empty candidate list.
if label:
labeled = [row for row in new_torrents if len(row) > 2 and row[2] == label]
if labeled:
new_torrents = labeled
for row in new_torrents:
if len(row) > 1 and row[1] == name:
return str(row[0]).lower()
if known_hashes is not None and len(new_torrents) == 1:
return str(new_torrents[0][0]).lower()
time.sleep(0.5)
return None
def _get_torrent_path(self, download_id: str) -> str | None:
"""Get the file path of a torrent by hash.
+8 -1
View File
@@ -748,11 +748,18 @@ def prowlarr_clients_settings() -> list[SettingsField]:
TextField(
key="RTORRENT_LABEL",
label="Book Label",
description="Label to assign to book downloads in rTorrent",
description="Label to assign to ebook downloads in rTorrent",
placeholder="cwabd",
default="cwabd",
show_when={"field": "PROWLARR_TORRENT_CLIENT", "value": "rtorrent"},
),
TextField(
key="RTORRENT_AUDIOBOOK_LABEL",
label="Audiobook Label",
description="Label to assign to audiobook downloads in rTorrent (falls back to Book Label if not set)",
placeholder="audiobooks",
show_when={"field": "PROWLARR_TORRENT_CLIENT", "value": "rtorrent"},
),
TextField(
key="RTORRENT_DOWNLOAD_DIR",
label="Download Directory",
+102 -38
View File
@@ -5,8 +5,10 @@ from __future__ import annotations
import base64
import hashlib
import re
import time
from binascii import Error as BinasciiError
from dataclasses import dataclass
from threading import Lock
from urllib.parse import ParseResult, parse_qs, urljoin, urlparse
import requests
@@ -19,6 +21,7 @@ from shelfmark.download.network import get_ssl_verify
logger = setup_logger(__name__)
_MAGNET_RESPONSE_MAX_BYTES = 2000
_TORRENT_FETCH_MAX_REDIRECTS = 5
_BASE32_BTMH_TAG_BYTES = 34
_BTIH_INFO_BYTE_HEX = 0x20
_BTIH_PREFIX_BYTE = 0x12
@@ -35,6 +38,15 @@ _TORRENT_FETCH_ERRORS = (
_TORRENT_PARSE_ERRORS = (IndexError, KeyError, TypeError, ValueError)
_TRUSTED_TORRENT_FETCH_URL_CONFIG_KEYS = ("PROWLARR_URL", "NEWZNAB_URL")
# Successful torrent fetches are reused for a short window so one add attempt
# hits the download link only once. Tracker download links (e.g. private
# trackers behind Prowlarr's proxy) can be slow, rate-limited, or single-use,
# and both find_existing() and add_download() resolve the same URL (#1111).
_TORRENT_FETCH_CACHE_TTL_SECONDS = 120.0
_TORRENT_FETCH_CACHE_MAX_ENTRIES = 8
_torrent_fetch_cache_lock = Lock()
_torrent_fetch_cache: dict[str, tuple[float, TorrentInfo]] = {}
type BencodeValue = dict[str | bytes, BencodeValue] | list[BencodeValue] | int | bytes | str
@@ -54,6 +66,9 @@ class TorrentInfo:
magnet_url: str | None = None
"""The actual magnet URL, if available."""
fetch_error: str | None = None
"""Why fetching the .torrent URL failed, or None if it succeeded/was skipped."""
def with_info_hash(self, info_hash: str | None) -> TorrentInfo:
"""Return a copy with the info_hash replaced when provided."""
if info_hash:
@@ -62,6 +77,7 @@ class TorrentInfo:
torrent_data=self.torrent_data,
is_magnet=self.is_magnet,
magnet_url=self.magnet_url,
fetch_error=self.fetch_error,
)
return self
@@ -95,10 +111,58 @@ def extract_torrent_info(
# Not a magnet - try to fetch and parse the .torrent file
if not fetch_torrent:
return TorrentInfo(info_hash=expected_hash, torrent_data=None, is_magnet=False)
if not _is_trusted_torrent_fetch_url(url):
logger.debug("Skipping torrent prefetch for untrusted URL: %s...", url[:80])
return TorrentInfo(info_hash=expected_hash, torrent_data=None, is_magnet=False)
info = _get_cached_torrent_fetch(url)
if info is None:
info = _fetch_torrent_info(url)
if info.fetch_error is None:
_store_cached_torrent_fetch(url, info)
return info.with_info_hash(info.info_hash or expected_hash)
def _get_cached_torrent_fetch(url: str) -> TorrentInfo | None:
with _torrent_fetch_cache_lock:
entry = _torrent_fetch_cache.get(url)
if entry is None:
return None
fetched_at, info = entry
if time.monotonic() - fetched_at > _TORRENT_FETCH_CACHE_TTL_SECONDS:
del _torrent_fetch_cache[url]
return None
logger.debug("Reusing recently fetched torrent data for: %s...", url[:80])
return info
def _store_cached_torrent_fetch(url: str, info: TorrentInfo) -> None:
with _torrent_fetch_cache_lock:
_torrent_fetch_cache[url] = (time.monotonic(), info)
while len(_torrent_fetch_cache) > _TORRENT_FETCH_CACHE_MAX_ENTRIES:
oldest_url = min(_torrent_fetch_cache, key=lambda key: _torrent_fetch_cache[key][0])
del _torrent_fetch_cache[oldest_url]
def clear_torrent_fetch_cache() -> None:
"""Drop all cached torrent fetches (used by tests)."""
with _torrent_fetch_cache_lock:
_torrent_fetch_cache.clear()
def _fetch_torrent_info(url: str) -> TorrentInfo:
"""Fetch a .torrent URL and parse out the info_hash and raw torrent data.
On failure, the returned TorrentInfo carries the reason in `fetch_error`
so callers can surface it instead of a generic hash error.
"""
# A release source can legitimately hand us a download URL on a different
# origin than the configured Prowlarr/Newznab endpoint (e.g. a direct
# tracker link, or Prowlarr reached through a separate proxy), and a trusted
# Prowlarr download URL commonly redirects to the indexer's own download
# link. We still need to fetch the .torrent to recover the info_hash when
# the source did not provide one, so the prefetch runs regardless of origin
# and follows cross-origin redirects. The Prowlarr API key, however, is
# re-evaluated per hop and only ever sent to a trusted origin so it can
# never leak to an arbitrary indexer/tracker host.
headers: dict[str, str] = {"Accept": "application/x-bittorrent"}
# TODO(shelfmark): Move this source-specific Prowlarr auth handling into a source hook.
api_key = str(config.get("PROWLARR_API_KEY", "") or "").strip()
@@ -114,44 +178,47 @@ def extract_torrent_info(
try:
logger.debug("Fetching torrent file from: %s...", url[:80])
# Use allow_redirects=False to handle magnet link redirects manually
# Some indexers redirect download URLs to magnet links
resp = requests.get(
url,
timeout=30,
allow_redirects=False,
headers=headers,
verify=get_ssl_verify(url),
)
# Redirects are followed manually: some indexers redirect download URLs
# to magnet links, and each hop must decide anew whether it may see the
# API key.
current_url = url
redirects_remaining = _TORRENT_FETCH_MAX_REDIRECTS
while True:
request_headers = dict(headers)
if not _is_trusted_torrent_fetch_url(current_url):
request_headers.pop("X-Api-Key", None)
# Check if this is a redirect to a magnet link
if resp.status_code in (301, 302, 303, 307, 308):
redirect_url = resolve_url(url, resp.headers.get("Location", ""))
resp = requests.get(
current_url,
timeout=30,
allow_redirects=False,
headers=request_headers,
verify=get_ssl_verify(current_url),
)
if resp.status_code not in (301, 302, 303, 307, 308):
break
redirect_url = resolve_url(current_url, resp.headers.get("Location", ""))
if redirect_url.startswith("magnet:"):
logger.debug("Download URL redirected to magnet link")
info_hash = extract_hash_from_magnet(redirect_url)
if not info_hash and expected_hash:
info_hash = expected_hash
return TorrentInfo(
info_hash=info_hash,
info_hash=extract_hash_from_magnet(redirect_url),
torrent_data=None,
is_magnet=True,
magnet_url=redirect_url,
)
if not _is_trusted_torrent_fetch_url(redirect_url):
logger.debug(
"Skipping torrent prefetch redirect to untrusted URL: %s...",
redirect_url[:80],
if redirects_remaining <= 0:
logger.warning("Too many redirects fetching torrent file: %s...", url[:80])
return TorrentInfo(
info_hash=None,
torrent_data=None,
is_magnet=False,
fetch_error="too many redirects",
)
return TorrentInfo(info_hash=expected_hash, torrent_data=None, is_magnet=False)
# Not a magnet redirect, follow it manually
redirects_remaining -= 1
logger.debug("Following redirect to: %s...", redirect_url[:80])
resp = requests.get(
redirect_url,
timeout=30,
headers=headers,
verify=get_ssl_verify(redirect_url),
)
current_url = redirect_url
resp.raise_for_status()
torrent_data = resp.content
@@ -162,25 +229,22 @@ def extract_torrent_info(
text_content = torrent_data.decode("utf-8", errors="ignore").strip()
if text_content.startswith("magnet:"):
logger.debug("Download URL returned magnet link as response body")
info_hash = extract_hash_from_magnet(text_content)
if not info_hash and expected_hash:
info_hash = expected_hash
return TorrentInfo(
info_hash=info_hash,
info_hash=extract_hash_from_magnet(text_content),
torrent_data=None,
is_magnet=True,
magnet_url=text_content,
)
info_hash = extract_info_hash_from_torrent(torrent_data) or expected_hash
info_hash = extract_info_hash_from_torrent(torrent_data)
if info_hash:
logger.debug("Extracted hash from torrent file: %s", info_hash)
else:
logger.warning("Could not extract hash from torrent file")
return TorrentInfo(info_hash=info_hash, torrent_data=torrent_data, is_magnet=False)
except _TORRENT_FETCH_ERRORS as e:
logger.debug("Could not fetch torrent file: %s", e)
return TorrentInfo(info_hash=expected_hash, torrent_data=None, is_magnet=False)
logger.warning("Could not fetch torrent file: %s", e)
return TorrentInfo(info_hash=None, torrent_data=None, is_magnet=False, fetch_error=str(e))
def _is_trusted_torrent_fetch_url(url: str) -> bool:
+6 -2
View File
@@ -316,8 +316,12 @@ class TransmissionClient(DownloadClient):
state, message = status_map.get(status_value, ("downloading", "Downloading"))
progress = torrent.percent_done * 100
# Only mark complete when seeding - seed pending means files still being moved
complete = progress >= _SEEDING_PROGRESS_PERCENT and status_value == "seeding"
# Only mark complete when seeding or stopped (e.g. if seed limit/ratio is 0)
# and progress is complete. seed pending means files still being moved
complete = progress >= _SEEDING_PROGRESS_PERCENT and status_value in (
"seeding",
"stopped",
)
if complete:
message = "Complete"
+93
View File
@@ -852,6 +852,99 @@ def _init_custom_resolver_internal(servers: list[str]) -> dns.resolver.Resolver:
return custom_resolver
# --- ISP / network DNS interference detection ---------------------------------
# Compare what the (tamperable) system resolver returns for a host against a
# tamper-resistant DoH lookup. Divergent answers are a strong signal the network is
# hijacking or NXDOMAIN-blocking the domain (a common reason AA downloads "work" but
# land on an ISP block page). Used to surface an actionable hint to the user.
_dns_interference_warned: set[str] = set()
_dns_interference_active = False
def _build_detection_doh_resolver() -> DoHResolver | None:
"""Build a throwaway DoH resolver for interference checks (no socket patching).
Honours the DoH provider the user selected (``DNS_PROVIDERS[_current_dns_index]``),
falling back to the first configured provider when none is active. The endpoint is
pinned to the provider's own nameserver IP so resolving the DoH host can't be
redirected by the very DNS layer the check is meant to detect.
"""
if 0 <= _current_dns_index < len(DNS_PROVIDERS):
_name, servers, doh_url = DNS_PROVIDERS[_current_dns_index]
elif DNS_PROVIDERS:
_name, servers, doh_url = DNS_PROVIDERS[0]
else:
return None
server_hostname = urllib.parse.urlparse(doh_url).hostname or ""
if not server_hostname or not servers:
return None
return DoHResolver(doh_url, server_hostname, servers[0])
def detect_dns_interference(hostname: str) -> dict[str, list[str]] | None:
"""Detect network DNS interference by comparing system DNS against DoH.
Returns ``{"system_ips": [...], "doh_ips": [...]}`` when the two resolvers disagree
(no overlapping IPs), otherwise None. No-op for IP literals / local hostnames and
when DoH resolution is unavailable, so it never produces a false positive.
"""
host = (hostname or "").strip().lower()
if not host or _is_ip_address(host) or _is_local_address(host):
return None
resolver = _build_detection_doh_resolver()
if resolver is None:
return None
try:
system_ips = {str(info[4][0]) for info in original_getaddrinfo(host, 443, socket.AF_INET)}
except OSError:
return None
if not system_ips:
return None
doh_ips = {ip for ip in resolver.resolve(host, "A") if ip}
if not doh_ips or (system_ips & doh_ips):
return None
return {"system_ips": sorted(system_ips), "doh_ips": sorted(doh_ips)}
def note_possible_dns_interference(hostname: str) -> bool:
"""Check ``hostname`` for DNS interference, logging an actionable warning once.
Returns True when interference has been detected this session. The check runs at
most once per host to avoid repeated DoH lookups and log spam.
"""
global _dns_interference_active
host = (hostname or "").strip().lower()
if not host or host in _dns_interference_warned:
return _dns_interference_active
_dns_interference_warned.add(host)
result = detect_dns_interference(host)
if not result:
return _dns_interference_active
_dns_interference_active = True
routing_via_doh = _current_dns_index >= 0 and bool(DOH_SERVER)
remedy = (
"Shelfmark is routing this domain through DNS-over-HTTPS to work around it."
if routing_via_doh
else "Enable DNS-over-HTTPS (USE_DOH=true) or set a custom DNS provider to bypass it."
)
logger.warning(
"Possible ISP/network DNS interference for %s: system DNS resolves to %s but DoH "
"resolves to %s. The network appears to be blocking or redirecting this domain. %s",
host,
result["system_ips"],
result["doh_ips"],
remedy,
)
return True
def dns_interference_detected() -> bool:
"""Whether network DNS interference has been detected this session."""
return _dns_interference_active
def init_doh_resolver(doh_server: str = "") -> DoHResolver | None:
"""Initialize DNS over HTTPS resolver."""
server = doh_server or DOH_SERVER
+19 -7
View File
@@ -170,16 +170,19 @@ def _build_retry_resolution_fields(
retry_download_url = normalize_optional_text(release_data.get("download_url"))
protocol = normalize_optional_text(release_data.get("protocol"))
source = normalize_optional_text(release_data.get("source"))
retry_source_context: dict[str, Any] = {}
if source is not None:
handler = get_handler(source)
source_retry_fields = handler.build_retry_resolution_fields(release_data)
retry_download_url = (
normalize_optional_text(source_retry_fields.get("retry_download_url"))
or retry_download_url
)
protocol = (
normalize_optional_text(source_retry_fields.get("retry_download_protocol")) or protocol
)
if "retry_download_url" in source_retry_fields:
retry_download_url = normalize_optional_text(
source_retry_fields.get("retry_download_url")
)
if "retry_download_protocol" in source_retry_fields:
protocol = normalize_optional_text(source_retry_fields.get("retry_download_protocol"))
raw_retry_source_context = source_retry_fields.get("retry_source_context")
if isinstance(raw_retry_source_context, dict):
retry_source_context = dict(raw_retry_source_context)
ratio_limit = _optional_number(release_data.get("ratio_limit"))
if ratio_limit is None and config.get("PROWLARR_USE_SEED_PREFERENCES", False):
@@ -202,6 +205,7 @@ def _build_retry_resolution_fields(
),
"retry_ratio_limit": ratio_limit,
"retry_seeding_time_limit_minutes": seeding_time_limit_minutes,
"retry_source_context": retry_source_context,
"can_retry_without_staged_source": True,
}
@@ -400,6 +404,7 @@ def serialize_task_for_retry(task: DownloadTask) -> dict[str, Any]:
search_mode = normalized_search_mode or None
raw_output_args = getattr(task, "output_args", None)
raw_retry_source_context = getattr(task, "retry_source_context", None)
return {
"task_id": getattr(task, "task_id", None),
@@ -428,6 +433,9 @@ def serialize_task_for_retry(task: DownloadTask) -> dict[str, Any]:
"retry_expected_hash": getattr(task, "retry_expected_hash", None),
"retry_ratio_limit": getattr(task, "retry_ratio_limit", None),
"retry_seeding_time_limit_minutes": getattr(task, "retry_seeding_time_limit_minutes", None),
"retry_source_context": (
dict(raw_retry_source_context) if isinstance(raw_retry_source_context, dict) else {}
),
"can_retry_without_staged_source": bool(
getattr(task, "can_retry_without_staged_source", True)
),
@@ -453,6 +461,7 @@ def _restore_task_from_retry_payload(payload: object) -> DownloadTask | None:
search_mode = None
output_args = payload.get("output_args")
retry_source_context = payload.get("retry_source_context")
return DownloadTask(
task_id=task_id,
@@ -483,6 +492,9 @@ def _restore_task_from_retry_payload(payload: object) -> DownloadTask | None:
retry_seeding_time_limit_minutes=_optional_positive_int(
payload.get("retry_seeding_time_limit_minutes")
),
retry_source_context=(
dict(retry_source_context) if isinstance(retry_source_context, dict) else {}
),
can_retry_without_staged_source=bool(payload.get("can_retry_without_staged_source", True)),
)
@@ -2,6 +2,7 @@
from __future__ import annotations
import contextlib
import uuid
from typing import TYPE_CHECKING
@@ -40,9 +41,11 @@ def validate_destination(
status_callback("error", f"Destination is not a directory: {destination}")
return False
created_by_us = False
if not destination_exists:
try:
run_blocking_io(destination.mkdir, parents=True, exist_ok=True)
created_by_us = True
except (OSError, PermissionError) as exc:
log_path_permission_context("destination_create", destination)
logger.warning("Cannot create destination: %s (%s)", destination, exc)
@@ -63,6 +66,9 @@ def validate_destination(
log_path_permission_context("destination_write_probe", destination)
logger.warning("Destination not writable: %s (%s)", destination, exc)
status_callback("error", f"Destination not writable: {destination} ({exc})")
if created_by_us:
with contextlib.suppress(OSError):
run_blocking_io(destination.rmdir)
return False
return True
+3
View File
@@ -1163,6 +1163,9 @@ def api_config() -> Response | tuple[Response, int]:
"show_combined_selector": app_config.get(
"SHOW_COMBINED_SELECTOR", True, user_id=db_user_id
),
"force_combined_search": app_config.get(
"FORCE_COMBINED_SEARCH", False, user_id=db_user_id
),
"books_output_mode": app_config.get("BOOKS_OUTPUT_MODE", "folder"),
"auto_open_downloads_sidebar": app_config.get("AUTO_OPEN_DOWNLOADS_SIDEBAR", True),
"hardcover_auto_remove_on_download": app_config.get(
+1 -1
View File
@@ -2628,7 +2628,7 @@ class HardcoverProvider(MetadataProvider):
raise RuntimeError(msg) from e
return None
except requests.HTTPError as e:
if e.response.status_code == HTTPStatus.UNAUTHORIZED:
if e.response is not None and e.response.status_code == HTTPStatus.UNAUTHORIZED:
logger.exception("Hardcover API key is invalid")
if raise_on_error:
msg = "Hardcover API key is invalid"
+3 -3
View File
@@ -214,7 +214,7 @@ class OpenLibraryProvider(MetadataProvider):
logger.warning("Open Library search timed out")
return []
except requests.HTTPError as e:
if e.response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
if e.response is not None and e.response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
logger.warning("Open Library service unavailable (503)")
else:
logger.exception("Open Library HTTP error")
@@ -253,7 +253,7 @@ class OpenLibraryProvider(MetadataProvider):
logger.warning("Open Library get_book timed out")
return None
except requests.HTTPError as e:
if e.response.status_code == HTTPStatus.NOT_FOUND:
if e.response is not None and e.response.status_code == HTTPStatus.NOT_FOUND:
logger.debug("Open Library work not found: %s", book_id)
else:
logger.exception("Open Library HTTP error")
@@ -314,7 +314,7 @@ class OpenLibraryProvider(MetadataProvider):
return self._parse_edition(edition, clean_isbn)
except requests.HTTPError as e:
if e.response.status_code == HTTPStatus.NOT_FOUND:
if e.response is not None and e.response.status_code == HTTPStatus.NOT_FOUND:
logger.debug("Open Library ISBN not found: %s", isbn)
else:
logger.exception("Open Library ISBN search HTTP error")
@@ -417,6 +417,18 @@ def extract_magnet_link(details_url: str, hostname: str = "audiobookbay.lu") ->
# Clean up info hash (remove whitespace, ensure uppercase)
info_hash = re.sub(r"\s+", "", info_hash).upper()
# Validate: SHA1 = 40 hex chars, SHA256 = 64 hex chars
if not re.match(r"^[0-9A-F]{40}$|^[0-9A-F]{64}$", info_hash):
logger.warning("Info Hash invalid (got %r), trying magnet fallback.", info_hash)
# Fallback: search entire page for a complete magnet link (e.g. posted in comments)
magnet_match = re.search(r"magnet:\?xt=urn:btih:([0-9a-fA-F]{40,64})", detail_html)
if magnet_match:
info_hash = magnet_match.group(1).upper()
logger.info("Found hash via magnet fallback: %s", info_hash)
else:
logger.warning("No valid magnet link found on page, giving up.")
return None
# 2. Extract Trackers
# Find all <td> containing udp:// or http://
trackers = []
@@ -238,8 +238,8 @@ class AudiobookBaySource(ReleaseSource):
exact_phrase=exact_phrase,
)
# For auto-generated queries, fallback to broad matching if exact phrase returns nothing.
if exact_phrase and not results and not plan.manual_query:
# Fallback to broad matching if exact phrase returns nothing (manual or auto query).
if exact_phrase and not results:
logger.info(
"No exact phrase results, retrying AudiobookBay search without quotes"
)
@@ -288,7 +288,7 @@ class AudiobookBaySource(ReleaseSource):
size_str = result.get("size")
size_bytes = parse_size(size_str) if size_str else None
language_raw = result.get("language")
language_code = _map_language(language_raw) if language_raw else None
language_code = _map_language(language_raw) if language_raw else "en"
bitrate = result.get("bitrate")
bitrate_kbps = _parse_bitrate_to_kbps(bitrate)
+320 -23
View File
@@ -3,9 +3,12 @@
import itertools
import json
import re
import threading
import time
import unicodedata
from dataclasses import replace
from http import HTTPStatus
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar, NoReturn, TypedDict
from urllib.parse import quote, urlparse
@@ -197,6 +200,49 @@ _SOURCE_FAILURE_THRESHOLD = 4
_MIN_VALID_FILE_SIZE = 10 * 1024
_AA_COUNTDOWN_MAX_SECONDS = 300
# --- Distant-path language detection ---
_DISTANT_PATH_EXTENSIONS = (
"epub",
"mobi",
"azw3",
"fb2",
"djvu",
"cbz",
"cbr",
"pdf",
"zip",
"rar",
"m4b",
"mp3",
)
_DISTANT_PATH_EXTENSION_PATTERN = "|".join(re.escape(e) for e in _DISTANT_PATH_EXTENSIONS)
_DISTANT_PATH_PATTERN = re.compile(
rf"(?:[A-Za-z0-9._-]+/)?[A-Za-z]:(?:\\|/)[^\n\r<>\"]+?\.(?:{_DISTANT_PATH_EXTENSION_PATTERN})\b",
re.IGNORECASE,
)
_DISTANT_PATH_FALLBACK_PATTERN = re.compile(
r"(?:[A-Za-z0-9._-]+/)?[A-Za-z]:(?:\\|/)[^\n\r<>\"]+",
re.IGNORECASE,
)
_BRACKETED_LANGUAGE_CODE_PATTERN = re.compile(
r"\[(?:bd[\s._-]*)?([A-Za-z]{2,3})\]",
re.IGNORECASE,
)
_KEYED_LANGUAGE_CODE_PATTERN = re.compile(
r"\b(?:bd|lang(?:uage)?)\s*[:._-]?\s*([A-Za-z]{2,3})\b",
re.IGNORECASE,
)
_LANGUAGE_CODE_TOKEN_PATTERN = re.compile(
r"(?:^|[\s_./\\\-\[(])([A-Za-z]{2,3})(?=$|[\s_./\\\-)\]])"
)
_LANGUAGE_NAME_TOKEN_PATTERN = re.compile(r"[a-z]{4,}(?:-[a-z0-9]+)?")
_LANGUAGE_ALIAS_TO_CODE: dict[str, str] | None = None
_LANGUAGE_ALIAS_LOCK = threading.Lock()
_LANGUAGE_PLACEHOLDERS = frozenset({"", "-", "--", "unknown", "unk", "n/a", "na"})
# Short codes that appear in common words — require bracket/key context to accept
_AMBIGUOUS_SHORT_LANGUAGE_CODES = frozenset({"de", "en", "it", "la", "no", "or", "is", "in"})
# Sources that require Cloudflare bypass
_CF_BYPASS_REQUIRED = frozenset({"aa-slow-nowait", "aa-slow-wait", "zlib", "welib"})
@@ -204,6 +250,189 @@ _CF_BYPASS_REQUIRED = frozenset({"aa-slow-nowait", "aa-slow-wait", "zlib", "weli
_AA_PAGE_SOURCES = frozenset({"aa-slow-nowait", "aa-slow-wait"})
def _is_language_from_path_enabled() -> bool:
return bool(config.get("DIRECT_DOWNLOAD_LANGUAGE_FROM_PATH", False))
def _normalize_language_token(value: str) -> str:
normalized = value.strip().lower()
for dash in ("‑", "–", "—", "−"):
normalized = normalized.replace(dash, "-")
return normalized
def _fold_text(value: str) -> str:
normalized = unicodedata.normalize("NFKD", value)
return "".join(c for c in normalized if not unicodedata.combining(c)).lower()
def _language_alias_to_code() -> dict[str, str]:
"""Build alias→code map from bundled language metadata (lazy, cached)."""
global _LANGUAGE_ALIAS_TO_CODE
cached = _LANGUAGE_ALIAS_TO_CODE
if cached is not None:
return cached
with _LANGUAGE_ALIAS_LOCK:
cached = _LANGUAGE_ALIAS_TO_CODE
if cached is not None:
return cached
mapping: dict[str, str] = {}
data_path = Path(__file__).resolve().parents[2] / "data" / "book-languages.json"
try:
raw = json.loads(data_path.read_text(encoding="utf-8"))
except OSError, ValueError, TypeError:
_LANGUAGE_ALIAS_TO_CODE = {}
return _LANGUAGE_ALIAS_TO_CODE
if not isinstance(raw, list):
_LANGUAGE_ALIAS_TO_CODE = {}
return _LANGUAGE_ALIAS_TO_CODE
for item in raw:
if not isinstance(item, dict):
continue
code = _normalize_language_token(str(item.get("code", "")))
name = _normalize_language_token(str(item.get("language", "")))
if not code:
continue
mapping.setdefault(code, code)
mapping.setdefault(code.replace("-", "_"), code)
mapping.setdefault(code.split("-")[0], code)
mapping.setdefault(_fold_text(code), code)
if name:
mapping.setdefault(name, code)
mapping.setdefault(_fold_text(name), code)
_LANGUAGE_ALIAS_TO_CODE = mapping
return _LANGUAGE_ALIAS_TO_CODE
def _extract_distant_path(row: Tag, *, enabled: bool) -> str | None:
"""Extract the Windows-style file path from an AA search result row."""
if not enabled:
return None
def _normalize_candidate(text: str) -> str:
normalized = re.sub(r"\s*([\\/])\s*", r"\1", text)
normalized = re.sub(r":\s*([\\/])", r":\1", normalized)
return re.sub(
r"\s+\.(epub|mobi|azw3|fb2|djvu|cbz|cbr|pdf|zip|rar|m4b|mp3)\b",
r".\1",
normalized,
flags=re.IGNORECASE,
)
candidates = [row.get_text(" ", strip=True)]
for cell in row.find_all("td"):
cell_text = cell.get_text(" ", strip=True)
if cell_text:
candidates.append(cell_text)
best: str | None = None
for text in candidates:
for match in _DISTANT_PATH_PATTERN.findall(_normalize_candidate(text)):
candidate = match.strip().rstrip(".,;")
if best is None or len(candidate) > len(best):
best = candidate
if best is not None:
return best
for text in candidates:
for match in _DISTANT_PATH_FALLBACK_PATTERN.findall(_normalize_candidate(text)):
candidate = match.strip().rstrip(".,;")
if best is None or len(candidate) > len(best):
best = candidate
return best
def _detect_language_from_distant_path(path: str | None) -> str | None:
"""Infer a language code from distant-path tags such as [BD FR] or [Fr]."""
if not path:
return None
aliases = _language_alias_to_code()
if not aliases:
return None
folded_path = _fold_text(path)
strong_candidates: list[str] = []
for code in _BRACKETED_LANGUAGE_CODE_PATTERN.findall(path):
normalized = _normalize_language_token(code)
if normalized in aliases:
strong_candidates.append(aliases[normalized])
for code in _KEYED_LANGUAGE_CODE_PATTERN.findall(path):
normalized = _normalize_language_token(code)
if normalized in aliases:
strong_candidates.append(aliases[normalized])
non_ambiguous = [c for c in strong_candidates if c not in _AMBIGUOUS_SHORT_LANGUAGE_CODES]
if non_ambiguous:
return non_ambiguous[0]
for token in _LANGUAGE_NAME_TOKEN_PATTERN.findall(folded_path):
normalized = _normalize_language_token(token)
if normalized in aliases:
candidate = aliases[normalized]
if candidate not in _AMBIGUOUS_SHORT_LANGUAGE_CODES:
return candidate
if strong_candidates:
return strong_candidates[0]
for code in _LANGUAGE_CODE_TOKEN_PATTERN.findall(path):
normalized = _normalize_language_token(code)
if normalized in _AMBIGUOUS_SHORT_LANGUAGE_CODES:
continue
if normalized in aliases:
return aliases[normalized]
return None
def _is_missing_or_placeholder_language(language: str | None) -> bool:
if language is None:
return True
return _normalize_language_token(language) in _LANGUAGE_PLACEHOLDERS
def _normalize_requested_languages(languages: list[str] | None) -> set[str]:
if not languages:
return set()
aliases = _language_alias_to_code()
normalized: set[str] = set()
for value in languages:
token = _normalize_language_token(str(value))
if not token or token == "all": # noqa: S105 - "all" is a language sentinel
continue
normalized.add(aliases.get(token, token))
return normalized
def _book_matches_requested_languages(book_language: str | None, requested: set[str]) -> bool:
"""Return True when a book's language matches the requested filter.
Books with unknown/missing language always pass — the server-side &lang= filter
already narrowed the result set, so dropping unlabelled rows hides valid results.
"""
if not requested:
return True
if not book_language:
return True
aliases = _language_alias_to_code()
normalized_book = aliases.get(
_normalize_language_token(book_language),
_normalize_language_token(book_language),
)
return normalized_book in requested
def _is_configured_zlib_link(url: str) -> bool:
"""Return True when a URL belongs to a configured Z-Library mirror."""
from shelfmark.core.mirrors import get_zlib_cookie_domains
@@ -360,9 +589,17 @@ def search_books(query: str, filters: SearchFilters) -> list[BrowseRecord]:
filters_query = ""
for value in filters.lang or []:
if value and value != "all":
filters_query += f"&lang={quote(value)}"
path_language_enabled = _is_language_from_path_enabled()
requested_langs = _normalize_requested_languages(filters.lang)
# When path-language inference is on and a language is requested, skip the
# server-side &lang= filter: lgli files often have no AA language metadata
# and would be excluded before we can infer language from the distant path.
# Local filtering below handles the narrowing instead.
if not (path_language_enabled and requested_langs):
for value in filters.lang or []:
if value and value != "all":
filters_query += f"&lang={quote(value)}"
if filters.sort and filters.sort != "relevance":
filters_query += f"&sort={quote(filters.sort)}"
@@ -397,14 +634,13 @@ def search_books(query: str, filters: SearchFilters) -> list[BrowseRecord]:
msg = "Unable to reach download source. Network restricted or mirrors are blocked."
raise SearchUnavailableError(msg)
if "No files found." in html:
logger.info("No books found for query: %s", query)
return []
soup = BeautifulSoup(_html_response_text(html), "html.parser")
tbody = soup.find("table")
if tbody is None:
if "No files found." in html:
logger.info("No books found for query: %s", query)
return []
logger.warning("No results table found for query: %s", query)
msg = "No books found. Please try another query."
raise RuntimeError(msg)
@@ -418,6 +654,9 @@ def search_books(query: str, filters: SearchFilters) -> list[BrowseRecord]:
if book:
books.append(book)
if path_language_enabled and requested_langs:
books = [b for b in books if _book_matches_requested_languages(b.language, requested_langs)]
supported_formats = _get_supported_formats()
books.sort(
@@ -471,10 +710,23 @@ def _parse_search_result_row(row: Tag) -> BrowseRecord | None:
if not record_id:
return None
path_language_enabled = _is_language_from_path_enabled()
distant_path = _extract_distant_path(row, enabled=path_language_enabled)
preview_img = cells[0].find("img")
preview = _get_attr(preview_img, "src") if isinstance(preview_img, Tag) else None
title = _first_stripped_text(cells[1].find("span"))
title_span = cells[1].find("span")
if isinstance(title_span, Tag):
# AA nests related-edition spans inside the main title span — take only direct text.
direct = " ".join(
str(c).strip()
for c in title_span.children
if isinstance(c, NavigableString) and str(c).strip()
).strip()
title = direct or _first_stripped_text(title_span)
else:
title = None
author = _first_stripped_text(cells[2].find("span"))
publisher = _first_stripped_text(cells[3].find("span"))
year = _first_stripped_text(cells[4].find("span"))
@@ -483,18 +735,19 @@ def _parse_search_result_row(row: Tag) -> BrowseRecord | None:
file_format = _first_stripped_text(cells[9].find("span"))
size = _first_stripped_text(cells[10].find("span"))
if (
title is None
or author is None
or publisher is None
or year is None
or language is None
or content is None
or file_format is None
or size is None
):
# Only title and format are truly required — lgli rows often have sparse metadata
if title is None or file_format is None:
return None
# Skip entries where the title is a catalog format descriptor, not a real title
# e.g. "Book/Online Audio", "Print book" — lgli metadata pollution
if title and "/" in title and len(title) < 40 and not any(c.isdigit() for c in title):
return None
if path_language_enabled and _is_missing_or_placeholder_language(language):
detected = _detect_language_from_distant_path(distant_path)
language = detected or "unknown"
return BrowseRecord(
id=record_id,
title=title,
@@ -507,6 +760,7 @@ def _parse_search_result_row(row: Tag) -> BrowseRecord | None:
content=content.lower() if content else None,
format=file_format.lower() if file_format else None,
size=size,
download_path=distant_path,
)
except (AttributeError, IndexError, KeyError, TypeError) as e:
logger.error_trace(f"Error parsing search result row: {e}")
@@ -1229,6 +1483,9 @@ def _get_download_url(
return downloader.get_absolute_url(link, url)
_AA_COUNTDOWN_MAX_RETRIES = 3
def _extract_slow_download_url(
soup: BeautifulSoup,
link: str,
@@ -1237,6 +1494,7 @@ def _extract_slow_download_url(
status_callback: Callable[[str, str | None], None] | None,
selector: network.AAMirrorSelector,
source_context: str | None = None,
_countdown_attempts: int = 0,
) -> str:
"""Extract download URL from AA slow download pages."""
html_str = str(soup)
@@ -1301,6 +1559,14 @@ def _extract_slow_download_url(
countdown_seconds = _extract_countdown_seconds(soup, html_str)
if countdown_seconds > 0:
if _countdown_attempts >= _AA_COUNTDOWN_MAX_RETRIES:
logger.warning(
"Countdown retry limit (%s) reached for %s, giving up",
_AA_COUNTDOWN_MAX_RETRIES,
title,
)
return ""
max_countdown_seconds = 600
sleep_time = min(countdown_seconds, max_countdown_seconds)
if countdown_seconds > max_countdown_seconds:
@@ -1309,7 +1575,13 @@ def _extract_slow_download_url(
countdown_seconds,
max_countdown_seconds,
)
logger.info("AA waitlist: %ss for %s", sleep_time, title)
logger.info(
"AA waitlist: %ss for %s (attempt %s/%s)",
sleep_time,
title,
_countdown_attempts + 1,
_AA_COUNTDOWN_MAX_RETRIES,
)
# Live countdown with status updates
for remaining in range(sleep_time, 0, -1):
@@ -1330,12 +1602,31 @@ def _extract_slow_download_url(
if status_callback and source_context:
status_callback("resolving", f"{source_context} - Fetching")
return _get_download_url(
link, title, cancel_flag, status_callback, selector, source_context
html = downloader.html_get_page(
link, selector=selector, cancel_flag=cancel_flag, status_callback=status_callback
)
if not html:
return ""
new_soup = BeautifulSoup(_html_response_text(html), "html.parser")
return _extract_slow_download_url(
new_soup,
link,
title,
cancel_flag,
status_callback,
selector,
source_context,
_countdown_attempts + 1,
)
link_texts = [a.get_text(strip=True)[:50] for a in soup.find_all("a", href=True)[:10]]
logger.warning("No download URL found. First 10 links: %s", link_texts)
# A bypassed page with no AA download links often means the network served a wrong
# page (e.g. an ISP block page) instead of Anna's Archive. Probe for DNS interference
# so we can give the user an actionable hint instead of a generic failure.
host = urlparse(link).hostname or ""
if host:
network.note_possible_dns_interference(host)
return ""
@@ -1646,7 +1937,6 @@ class DirectDownloadSource(ReleaseSource):
except Exception:
logger.exception("Search error")
logger.info("Found %s releases via title+author", len(all_results))
return [_browse_record_to_release(record) for record in all_results]
def is_available(self) -> bool:
@@ -1769,7 +2059,14 @@ class DirectDownloadHandler(DownloadHandler):
return None
if not success_url:
status_callback("error", "All download sources failed")
if network.dns_interference_detected():
status_callback(
"error",
"All sources failed - your network/ISP appears to be blocking "
"Anna's Archive. Enable DNS-over-HTTPS in settings.",
)
else:
status_callback("error", "All download sources failed")
return None
# Return temp path - orchestrator handles post-processing (archive extraction, ingest)
+21 -46
View File
@@ -13,7 +13,6 @@ from typing import Any
from shelfmark.config import env
from shelfmark.core.logger import setup_logger
from shelfmark.core.utils import is_audiobook as check_audiobook
from shelfmark.release_sources import Release, ReleaseProtocol
logger = setup_logger(__name__)
@@ -56,12 +55,6 @@ def _coerce_timestamp(value: object) -> float:
return 0.0
def _generate_cache_key(provider: str, provider_id: str, content_type: str | None = None) -> str:
"""Generate a cache key from provider, provider_id, and content type."""
normalized_content_type = "audiobook" if check_audiobook(content_type) else "ebook"
return f"{provider}:{provider_id}:{normalized_content_type}"
def _load_cache() -> dict[str, Any]:
"""Load cache from disk."""
try:
@@ -103,17 +96,17 @@ def _dict_to_release(data: dict[str, Any]) -> Release:
def get_cached_results(
provider: str,
provider_id: str,
content_type: str | None = None,
cache_key: str,
ttl_seconds: int | None = None,
) -> dict[str, Any] | None:
"""Get cached search results for a book.
"""Get the cached IRC answer for a query identity (server:channel:query).
The cache stores the whole answer (releases for all content types) under the query
identity, so it is not isolated by book or content type. Callers filter by content
type after reading.
Args:
provider: Metadata provider name (e.g., "hardcover", "openlibrary")
provider_id: Book ID in the provider's system
content_type: Search content type for cache isolation
cache_key: Query identity (e.g. "server:channel:query")
ttl_seconds: Cache TTL in seconds (from settings)
Returns:
@@ -127,8 +120,6 @@ def get_cached_results(
ttl_value = config.get("IRC_CACHE_TTL", DEFAULT_CACHE_TTL)
ttl_seconds = _coerce_cache_ttl(ttl_value, DEFAULT_CACHE_TTL)
cache_key = _generate_cache_key(provider, provider_id, content_type)
with _cache_lock:
cache = _load_cache()
entry = cache.get("entries", {}).get(cache_key)
@@ -141,10 +132,9 @@ def get_cached_results(
age = time.time() - cached_at
if ttl_seconds != 0 and age > ttl_seconds:
title = entry.get("title", cache_key)
logger.debug(
"IRC cache expired for '%s' (age: %.0fs > TTL: %ss)",
title,
entry.get("title", cache_key),
age,
ttl_seconds,
)
@@ -153,44 +143,36 @@ def get_cached_results(
# Convert dicts back to Release objects
releases = [_dict_to_release(r) for r in entry.get("releases", [])]
online_servers = entry.get("online_servers", [])
title = entry.get("title", "")
logger.info(
"IRC cache hit for '%s' (%s releases, age: %.0fs)",
title,
entry.get("title", ""),
len(releases),
age,
)
return {
"releases": releases,
"online_servers": online_servers,
"online_servers": entry.get("online_servers", []),
"cached_at": cached_at,
}
def cache_results(
provider: str,
provider_id: str,
cache_key: str,
title: str,
releases: list[Release],
content_type: str | None = None,
online_servers: list[str] | None = None,
) -> None:
"""Cache search results for a book.
"""Cache the whole IRC answer for a query identity.
Args:
provider: Metadata provider name
provider_id: Book ID in the provider's system
title: Book title (for logging/display)
releases: List of Release objects from search
content_type: Search content type for cache isolation
cache_key: Query identity (e.g. "server:channel:query")
title: Query text (for logging/display)
releases: All Release objects from the search (every content type)
online_servers: List of online server nicks (optional)
"""
cache_key = _generate_cache_key(provider, provider_id, content_type)
with _cache_lock:
cache = _load_cache()
@@ -198,9 +180,6 @@ def cache_results(
cache["entries"] = {}
cache["entries"][cache_key] = {
"provider": provider,
"provider_id": provider_id,
"content_type": "audiobook" if check_audiobook(content_type) else "ebook",
"title": title,
"releases": [_release_to_dict(r) for r in releases],
"online_servers": list(online_servers) if online_servers else [],
@@ -211,27 +190,23 @@ def cache_results(
logger.info("Cached %s IRC releases for '%s'", len(releases), title)
def invalidate_cache(provider: str, provider_id: str, content_type: str | None = None) -> bool:
def invalidate_cache(cache_key: str) -> bool:
"""Remove a specific entry from the cache.
Args:
provider: Metadata provider name
provider_id: Book ID in the provider's system
content_type: Search content type for cache isolation
cache_key: Query identity to remove
Returns:
True if entry was found and removed
"""
cache_key = _generate_cache_key(provider, provider_id, content_type)
with _cache_lock:
cache = _load_cache()
entry = cache.get("entries", {}).get(cache_key)
title = entry.get("title", cache_key) if entry else cache_key
entries = cache.get("entries", {})
if cache_key in cache.get("entries", {}):
del cache["entries"][cache_key]
if cache_key in entries:
title = entries[cache_key].get("title", cache_key)
del entries[cache_key]
_save_cache(cache)
logger.info("Invalidated IRC cache for '%s'", title)
return True
+5 -1
View File
@@ -88,7 +88,11 @@ def irc_settings() -> list[SettingsField]:
key="IRC_SEARCH_BOT",
label="Search bot",
placeholder="e.g. search",
description="The search bot to query for results",
description=(
"The search bot to address queries to (required). Searches are sent as "
'"@<bot> <query>".'
),
required=True,
env_supported=True,
),
HeadingField(
+135 -42
View File
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
from shelfmark.api.websocket import ws_manager
from shelfmark.core.config import config
from shelfmark.core.logger import setup_logger
from shelfmark.core.utils import is_audiobook
from shelfmark.release_sources import (
ColumnColorHint,
ColumnRenderType,
@@ -88,6 +89,17 @@ def _emit_status(message: str, phase: str = "searching") -> None:
MIN_SEARCH_INTERVAL = 15.0
_last_search_time: float = 0
# Anti-spam budget: the exact same message may only be posted to the channel a limited
# number of times within a rolling window. This stops a retry/refresh loop from flooding
# the channel with the same line over and over, while still allowing a few genuine retries
# (a search that came back empty can be tried again, and Refresh works until the budget runs
# out). Normal use never hits this: successful searches are served from the result cache
# without re-posting at all.
MAX_IDENTICAL_SENDS = 3
IDENTICAL_SEND_WINDOW_SECONDS = 24 * 60 * 60 # 24 hours
# message-send-key -> timestamps of recent posts of that exact message
_recent_message_sends: dict[str, list[float]] = {}
def _enforce_rate_limit() -> None:
"""Ensure minimum time between searches."""
@@ -102,6 +114,36 @@ def _enforce_rate_limit() -> None:
_last_search_time = time.time()
def _query_identity(server: str, channel: str, query: str) -> str:
"""Stable identity for a query on a given IRC server-channel.
Used as BOTH the result-cache key and the per-query send-counter key, so the same
query shares one cached answer and one send budget regardless of which book or
content type triggered it.
"""
return f"{server.casefold()}:{channel.casefold()}:{query.strip().casefold()}"
def _recent_send_count(key: str) -> int:
"""Number of times this exact message was posted within the rolling window."""
cutoff = time.time() - IDENTICAL_SEND_WINDOW_SECONDS
timestamps = [ts for ts in _recent_message_sends.get(key, []) if ts > cutoff]
if timestamps:
_recent_message_sends[key] = timestamps
else:
_recent_message_sends.pop(key, None)
return len(timestamps)
def _record_message_sent(key: str) -> None:
"""Record that an exact message was just posted to the channel."""
now = time.time()
cutoff = now - IDENTICAL_SEND_WINDOW_SECONDS
timestamps = [ts for ts in _recent_message_sends.get(key, []) if ts > cutoff]
timestamps.append(now)
_recent_message_sends[key] = timestamps
@register_source("irc")
class IRCReleaseSource(ReleaseSource):
"""Search IRC channels for ebook and audiobook releases."""
@@ -117,11 +159,16 @@ class IRCReleaseSource(ReleaseSource):
self._online_servers: set[str] | None = None
def is_available(self) -> bool:
"""Check if IRC is configured (server, channel, and nick are set)."""
"""Check if IRC is configured (server, channel, nick, and search bot are set).
The search bot is required: without it we would post bare queries straight
to the channel, which reads as spam and gets the nick banned.
"""
server = _config_text("IRC_SERVER")
channel = _config_text("IRC_CHANNEL")
nick = _config_text("IRC_NICK")
return bool(server and channel and nick)
search_bot = _config_text("IRC_SEARCH_BOT")
return bool(server and channel and nick and search_bot)
def get_column_config(self) -> ReleaseColumnConfig:
"""Configure UI columns for IRC results."""
@@ -179,25 +226,12 @@ class IRCReleaseSource(ReleaseSource):
logger.debug("IRC source is disabled, skipping search")
return []
# Check cache first (unless expand_search/refresh is requested)
if not expand_search:
cached = get_cached_results(book.provider, book.provider_id, content_type=content_type)
if cached:
_emit_status("Using cached results", phase="complete")
self._online_servers = set(cached.get("online_servers", []))
return cached["releases"]
# Build search query
query = plan.primary_query or self._build_query(book)
if not query:
logger.warning("No search query could be built")
return []
logger.info("IRC search: %s", query)
# Enforce rate limit
_enforce_rate_limit()
# Get IRC settings
server = _config_text("IRC_SERVER")
port = _config_port("IRC_PORT", 6697)
@@ -206,6 +240,54 @@ class IRCReleaseSource(ReleaseSource):
nick = _config_text("IRC_NICK")
search_bot = _config_text("IRC_SEARCH_BOT")
# Never post an unaddressed query to the channel. A bare book title looks like
# spam to everyone else in the channel and gets the nick banned. Searches must
# be addressed to a search bot ("@<bot> <query>").
if not search_bot:
logger.warning(
"IRC search bot not configured; refusing to post unaddressed query to channel"
)
_emit_status("IRC search bot not configured", phase="error")
return []
# One identity per query on this server-channel. The result cache and the send
# counter are both keyed on it: the SAME query shares one cached answer and one
# send budget regardless of which book/content type triggered it, while different
# queries are independent (searching 100 different books posts 100 messages).
requested = "audiobook" if is_audiobook(content_type) else "ebook"
query_key = _query_identity(server, channel, query)
# Serve the cached whole answer for an identical query (unless this is a refresh).
if not expand_search:
cached = get_cached_results(query_key)
if cached:
_emit_status("Using cached results", phase="complete")
self._online_servers = set(cached.get("online_servers", []))
return self._filter_by_content_type(cached["releases"], requested)
# Anti-spam cap: the exact same query may only be POSTED a limited number of times
# per window, even via refresh. Beyond that, serve whatever is cached rather than
# re-posting the identical message to the channel.
if _recent_send_count(query_key) >= MAX_IDENTICAL_SENDS:
logger.info(
"IRC query hit %s-send limit in window, not re-posting: %s",
MAX_IDENTICAL_SENDS,
query,
)
_emit_status(
"Search limit reached for this query — showing latest results", phase="complete"
)
cached = get_cached_results(query_key)
if cached:
self._online_servers = set(cached.get("online_servers", []))
return self._filter_by_content_type(cached["releases"], requested)
return []
logger.info("IRC search: %s", query)
# Enforce rate limit
_enforce_rate_limit()
client = None
try:
# Get or reuse IRC connection
@@ -221,28 +303,27 @@ class IRCReleaseSource(ReleaseSource):
# Capture online servers (elevated users in channel)
self._online_servers = client.online_servers
# Send search request
search_msg = f"@{search_bot} {query}" if search_bot else query
client.send_message(f"#{channel}", search_msg)
# Send search request (always addressed to the search bot, never bare)
client.send_message(f"#{channel}", f"@{search_bot} {query}")
_record_message_sent(query_key)
# Wait for results DCC - this is the long wait
# Wait for results DCC - this is the long wait.
# Don't restrict the sender to the trigger bot's nick: many channels answer an
# "@search" from a differently-named results bot. The DCC endpoint/filename are
# still validated, and wait_for_dcc falls back to the channel's server list.
_emit_status(f"Connected to #{channel} - Waiting for results...", phase="searching")
wait_kwargs = {"expected_senders": {search_bot}} if search_bot else {}
offer = client.wait_for_dcc(timeout=60.0, result_type=True, **wait_kwargs)
offer = client.wait_for_dcc(timeout=60.0, result_type=True)
online_servers = list(self._online_servers) if self._online_servers else None
if not offer:
logger.info("No search results received")
_emit_status("No results found", phase="complete")
# Release connection for reuse (don't close it)
connection_manager.release_connection(client)
# Cache empty result to avoid repeated failed searches
cache_results(
book.provider,
book.provider_id,
book.title,
[],
content_type=content_type,
online_servers=list(self._online_servers) if self._online_servers else None,
)
# Cache the (empty) answer under the query identity so an identical query
# is served from cache instead of re-posting.
cache_results(query_key, query, [], online_servers=online_servers)
return []
# Download results file
@@ -260,19 +341,22 @@ class IRCReleaseSource(ReleaseSource):
# Release connection for reuse (don't close it)
connection_manager.release_connection(client)
# Convert to Release objects
results = parse_results_file(content, content_type=content_type)
releases = self._convert_to_releases(results, content_type=content_type)
# Cache results
cache_results(
book.provider,
book.provider_id,
book.title,
releases,
content_type=content_type,
online_servers=list(self._online_servers) if self._online_servers else None,
# A single "@search" returns one file containing every format. Parse the whole
# answer (both ebooks and audiobooks) and cache it under the query identity, so
# requesting the other content type is served from cache without re-posting.
ebook_releases = self._convert_to_releases(
parse_results_file(content, content_type="ebook"), content_type="ebook"
)
audiobook_releases = self._convert_to_releases(
parse_results_file(content, content_type="audiobook"), content_type="audiobook"
)
cache_results(
query_key,
query,
ebook_releases + audiobook_releases,
online_servers=online_servers,
)
releases = audiobook_releases if requested == "audiobook" else ebook_releases
except DCCError as e:
logger.exception("DCC error during search")
@@ -390,6 +474,15 @@ class IRCReleaseSource(ReleaseSource):
return releases
@staticmethod
def _filter_by_content_type(releases: list[Release], requested: str) -> list[Release]:
"""Pick the requested content type out of a cached whole answer.
The cache stores releases for every content type under one query identity; each
release is tagged with its content type (defaulting to ebook when missing).
"""
return [release for release in releases if (release.content_type or "ebook") == requested]
@staticmethod
def _parse_size(size_str: str) -> int | None:
"""Parse human-readable size (e.g., '1.2MB', '500K') to bytes."""
+27 -7
View File
@@ -124,10 +124,12 @@ class ProwlarrClient:
msg = f"Invalid JSON response: {e}"
raise ValueError(msg) from e
except requests.exceptions.HTTPError as e:
status_code = e.response.status_code if e.response is not None else "unknown"
reason = e.response.reason if e.response is not None else "unknown"
logger.exception(
"Prowlarr API HTTP error: %s %s",
e.response.status_code,
e.response.reason,
status_code,
reason,
)
raise
except requests.exceptions.RequestException:
@@ -156,24 +158,35 @@ class ProwlarrClient:
logger.info("Prowlarr connection successful: version %s", version)
return True, f"Connected to Prowlarr {version}"
def get_indexers(self) -> list[dict[str, Any]]:
"""Get all configured indexers."""
def get_indexers(self, *, raise_on_error: bool = False) -> list[dict[str, Any]]:
"""Get all configured indexers.
Args:
raise_on_error: When True, propagate API failures instead of
returning an empty list. Callers that must distinguish
"no indexers" from "the request failed" should set this.
"""
try:
return _normalize_json_object_list(
self._request("GET", "/api/v1/indexer"),
context="Prowlarr indexer list",
)
except _PROWLARR_CLIENT_ERRORS:
if raise_on_error:
raise
logger.exception("Failed to get indexers")
return []
def get_enabled_indexers_detailed(self) -> list[dict[str, Any]]:
def get_enabled_indexers_detailed(
self, *, raise_on_error: bool = False
) -> list[dict[str, Any]]:
"""Get enabled indexers, including implementation metadata.
Note: Prowlarr indexer "name" is user-configurable; prefer
"implementation"/"implementationName" for stable identification.
"""
indexers = self.get_indexers()
indexers = self.get_indexers(raise_on_error=raise_on_error)
return [idx for idx in indexers if idx.get("enable", False)]
def get_enriched_indexer_ids(self, *, restrict_to: list[int] | None = None) -> list[int]:
@@ -212,10 +225,17 @@ class ProwlarrClient:
Prowlarr exposes seedTime in minutes, which is also the unit expected by
torrent clients.
Raises:
requests.exceptions.RequestException (and other client errors) when
the indexer list cannot be fetched. An empty dict strictly means
"no share limits are configured", never "the request failed" -
callers rely on this to avoid silently dropping seed limits.
"""
settings_by_indexer: dict[int, IndexerSeedSettings] = {}
for idx in self.get_enabled_indexers_detailed():
for idx in self.get_enabled_indexers_detailed(raise_on_error=True):
idx_id_int = coerce_int_like(idx.get("id"))
if idx_id_int is None:
continue
+185 -16
View File
@@ -1,10 +1,15 @@
"""Prowlarr download handler - resolves releases and delegates lifecycle to shared clients."""
from typing import TYPE_CHECKING, Any
from urllib.parse import urlparse
import requests
from shelfmark.core.config import config
from shelfmark.core.logger import setup_logger
from shelfmark.core.request_helpers import normalize_optional_text
from shelfmark.core.search_plan import build_release_search_plan
from shelfmark.core.utils import normalize_http_url
from shelfmark.download.clients import (
DownloadClient,
get_client,
@@ -23,8 +28,11 @@ from shelfmark.download.clients.base_handler import (
DownloadRequest,
ExternalClientHandler,
)
from shelfmark.metadata_providers import BookMetadata
from shelfmark.release_sources import register_handler
from shelfmark.release_sources.prowlarr.cache import get_release, remove_release
from shelfmark.release_sources.prowlarr.api import IndexerSeedSettings, ProwlarrClient
from shelfmark.release_sources.prowlarr.cache import cache_release, get_release, remove_release
from shelfmark.release_sources.prowlarr.source import ProwlarrSource
from shelfmark.release_sources.prowlarr.utils import (
coerce_int_like,
get_preferred_download_url,
@@ -37,6 +45,16 @@ if TYPE_CHECKING:
from shelfmark.core.models import DownloadTask
logger = setup_logger(__name__)
# Errors that ProwlarrClient can raise when fetching indexer settings.
_SEED_SETTINGS_FALLBACK_ERRORS = (
requests.exceptions.RequestException,
OSError,
RuntimeError,
TypeError,
ValueError,
)
__all__ = [
"ProwlarrHandler",
"POLL_INTERVAL",
@@ -49,6 +67,11 @@ __all__ = [
POLL_INTERVAL = _DEFAULT_POLL_INTERVAL
COMPLETED_PATH_RETRY_INTERVAL = _DEFAULT_COMPLETED_PATH_RETRY_INTERVAL
COMPLETED_PATH_MAX_ATTEMPTS = _DEFAULT_COMPLETED_PATH_MAX_ATTEMPTS
EXPIRED_LINK_REFRESH_ERROR = (
"The indexer download link expired and the release could not be refreshed. "
"Search again for a fresh result."
)
HASH_DETECTION_ERROR = "Could not determine torrent hash from URL"
def _coerce_positive_minutes(raw_minutes: object) -> int | None:
@@ -62,6 +85,47 @@ def _coerce_positive_minutes(raw_minutes: object) -> int | None:
class ProwlarrHandler(ExternalClientHandler):
"""Handler for Prowlarr downloads via configured torrent or usenet client."""
@staticmethod
def _build_prowlarr_client() -> ProwlarrClient | None:
"""Build a ProwlarrClient from config, or None if not configured."""
raw_url = config.get("PROWLARR_URL", "")
raw_api_key = config.get("PROWLARR_API_KEY", "")
url = normalize_optional_text(raw_url) if isinstance(raw_url, str) else None
api_key = normalize_optional_text(raw_api_key) if isinstance(raw_api_key, str) else None
if not url or not api_key:
return None
normalized_url = normalize_http_url(url)
if not normalized_url:
return None
return ProwlarrClient(normalized_url, api_key)
def _fetch_seed_settings_fallback(self, raw_indexer_id: object) -> IndexerSeedSettings | None:
"""Fetch share limits for one indexer directly from Prowlarr.
Used when the cached release is missing its search-time seed-limit
enrichment so that transient failures during search cannot cause a
torrent to be added without its configured share limits.
"""
indexer_id = coerce_int_like(raw_indexer_id)
if indexer_id is None:
return None
client = self._build_prowlarr_client()
if client is None:
return None
try:
settings = client.get_indexer_seed_settings(restrict_to=[indexer_id])
except _SEED_SETTINGS_FALLBACK_ERRORS:
logger.warning(
"Grab-time seed settings fallback failed for indexerId=%s",
indexer_id,
exc_info=True,
)
return None
return settings.get(indexer_id)
def _get_client(self, protocol: str) -> DownloadClient | None:
"""Compatibility shim so module-level patching still works in tests."""
return get_client(protocol)
@@ -81,18 +145,30 @@ class ProwlarrHandler(ExternalClientHandler):
def build_retry_resolution_fields(self, release_data: dict[str, Any]) -> dict[str, Any]:
source_id = normalize_optional_text(release_data.get("source_id"))
if source_id is None:
return {}
extra = release_data.get("extra")
if not isinstance(extra, dict):
extra = {}
prowlarr_result = get_release(source_id)
if prowlarr_result is None:
return {}
retry_source_context: dict[str, Any] = {}
indexer_id = release_data.get("indexer_id") or extra.get("indexer_id")
if indexer_id is not None:
retry_source_context["indexer_id"] = indexer_id
indexer = normalize_optional_text(release_data.get("indexer") or extra.get("indexer"))
if indexer is not None and indexer.lower() != "unknown":
retry_source_context["indexer"] = indexer
info_url = normalize_optional_text(release_data.get("info_url") or extra.get("info_url"))
if info_url is not None:
retry_source_context["info_url"] = info_url
if source_id is not None:
retry_source_context["source_id"] = source_id
return {
"retry_download_url": normalize_optional_text(
get_preferred_download_url(prowlarr_result)
),
"retry_download_protocol": normalize_optional_text(get_protocol(prowlarr_result)),
"retry_download_url": None,
"retry_download_protocol": None,
"retry_source_context": retry_source_context,
}
@classmethod
@@ -139,13 +215,12 @@ class ProwlarrHandler(ExternalClientHandler):
# Look up the cached release
prowlarr_result = get_release(task.task_id)
if not prowlarr_result:
restored_request = self._restore_download_request_from_task(task)
if restored_request is None:
logger.warning("Release cache miss: %s", task.task_id)
status_callback("error", "Release not found in cache (may have expired)")
logger.info("Prowlarr release cache miss, refreshing: %s", task.task_id)
prowlarr_result = self._refresh_release(task)
if prowlarr_result is None:
logger.warning("Prowlarr release refresh failed: %s", task.task_id)
status_callback("error", EXPIRED_LINK_REFRESH_ERROR)
return None
logger.info("Restored Prowlarr download request for retry: %s", task.task_id)
return restored_request
# Extract download URL
download_url = get_preferred_download_url(prowlarr_result)
@@ -171,6 +246,28 @@ class ProwlarrHandler(ExternalClientHandler):
seeding_time_limit = _coerce_positive_minutes(raw_configured_seed_time)
ratio_limit = float(raw_configured_ratio) if raw_configured_ratio is not None else None
# Fallback: search-time enrichment can be missing when the indexer
# settings fetch transiently failed during the search (#795).
# Re-resolve the limits from Prowlarr at grab time so torrents are
# never sent to the client without their configured share limits.
if seeding_time_limit is None and ratio_limit is None and protocol == "torrent":
fallback = self._fetch_seed_settings_fallback(prowlarr_result.get("indexerId"))
if fallback:
seeding_time_limit = _coerce_positive_minutes(
fallback.get("seeding_time_limit_minutes")
)
raw_ratio = fallback.get("ratio_limit")
ratio_limit = float(raw_ratio) if raw_ratio is not None else None
if seeding_time_limit is None and ratio_limit is None and protocol == "torrent":
logger.warning(
"Prowlarr seed preferences are enabled but no share limits "
"could be resolved for release '%s' (indexerId=%s); the "
"torrent will use the client's global limits",
release_name,
prowlarr_result.get("indexerId"),
)
return DownloadRequest(
url=download_url,
protocol=protocol,
@@ -180,6 +277,78 @@ class ProwlarrHandler(ExternalClientHandler):
ratio_limit=ratio_limit,
)
def _refresh_release(self, task: DownloadTask) -> dict[str, Any] | None:
"""Re-query Prowlarr and cache the exact original release if it still exists."""
title = normalize_optional_text(task.title)
if title is None:
return None
context = getattr(task, "retry_source_context", None)
if not isinstance(context, dict):
context = {}
indexer = normalize_optional_text(context.get("indexer"))
book = BookMetadata(
provider="shelfmark",
provider_id=task.task_id,
title=title,
authors=[task.author] if task.author else [],
search_title=title,
search_author=task.author,
)
plan = build_release_search_plan(
book,
indexers=[indexer] if indexer is not None else None,
)
source = ProwlarrSource()
results = source.search(book, plan, content_type=task.content_type or "ebook")
for release in results:
raw_release = get_release(release.source_id)
if raw_release is None:
continue
if not self._raw_release_matches_task(raw_release, task.task_id):
continue
cache_release(task.task_id, raw_release)
logger.info("Refreshed Prowlarr release: %s", task.task_id)
return raw_release
return None
@staticmethod
def _raw_release_matches_task(raw_release: dict[str, Any], task_id: str) -> bool:
identities = (
normalize_optional_text(raw_release.get("guid")),
normalize_optional_text(raw_release.get("infoUrl")),
)
return any(identity == task_id for identity in identities)
def _refresh_download_request_after_add_failure(
self,
*,
task: DownloadTask,
request: DownloadRequest,
error: Exception,
status_callback: Callable[[str, str | None], None],
) -> DownloadRequest | None:
"""Refresh once when a cached Prowlarr torrent proxy URL has expired."""
if request.protocol != "torrent":
return None
if HASH_DETECTION_ERROR not in str(error):
return None
parsed = urlparse(request.url)
if parsed.scheme.lower() not in {"http", "https"}:
return None
logger.info("Refreshing stale Prowlarr torrent URL for %s", task.task_id)
remove_release(task.task_id)
refreshed_request = self._resolve_download(task, status_callback)
if refreshed_request is None:
raise RuntimeError(EXPIRED_LINK_REFRESH_ERROR) from error
return refreshed_request
def _on_download_complete(self, task: DownloadTask) -> None:
"""Remove completed release from the Prowlarr cache."""
remove_release(task.task_id)
+39 -1
View File
@@ -2,8 +2,11 @@
import re
import time
from threading import Lock
from typing import TYPE_CHECKING, ClassVar, NoReturn
import requests
if TYPE_CHECKING:
from shelfmark.core.search_plan import ReleaseSearchPlan
from shelfmark.metadata_providers import BookMetadata
@@ -41,6 +44,11 @@ _SIZE_UNIT_BASE = 1024
_TWO_FORMATS = 2
_PROWLARR_SOURCE_ERRORS = (AttributeError, OSError, RuntimeError, TypeError, ValueError)
# Errors that can surface from ProwlarrClient.get_indexer_seed_settings(). The
# client raises requests exceptions (subclasses of OSError via IOError lineage
# is not guaranteed), so include RequestException explicitly.
_PROWLARR_SEED_SETTINGS_ERRORS = (*_PROWLARR_SOURCE_ERRORS, requests.exceptions.RequestException)
def _raise_timeout_error(message: str) -> NoReturn:
raise TimeoutError(message)
@@ -443,6 +451,36 @@ def _prowlarr_result_to_release(
)
# Last successfully fetched per-indexer share limits. Used as a fallback when
# a transient Prowlarr API failure prevents fetching fresh settings during a
# search, so results are never silently cached without seed limits (#795).
_seed_settings_lock = Lock()
_last_known_seed_settings: dict[int, IndexerSeedSettings] = {}
def _fetch_indexer_seed_settings(
client: ProwlarrClient,
indexer_ids: list[int] | None,
) -> dict[int, IndexerSeedSettings]:
"""Fetch per-indexer share limits, falling back to last-known-good on failure."""
try:
fetched = client.get_indexer_seed_settings(restrict_to=indexer_ids)
except _PROWLARR_SEED_SETTINGS_ERRORS:
with _seed_settings_lock:
fallback = dict(_last_known_seed_settings)
logger.warning(
"Failed to fetch Prowlarr indexer seed settings; "
"falling back to last known settings for %s indexer(s)",
len(fallback),
exc_info=True,
)
return fallback
with _seed_settings_lock:
_last_known_seed_settings.update(fetched)
return fetched
def _apply_indexer_seed_settings(
result: dict,
indexer_seed_settings: dict[int, IndexerSeedSettings],
@@ -783,7 +821,7 @@ class ProwlarrSource(ReleaseSource):
enriched_indexer_ids = client.get_enriched_indexer_ids(restrict_to=indexer_ids)
enriched_indexer_ids_set = set(enriched_indexer_ids)
indexer_seed_settings = (
client.get_indexer_seed_settings(restrict_to=indexer_ids)
_fetch_indexer_seed_settings(client, indexer_ids)
if config.get("PROWLARR_USE_SEED_PREFERENCES", False)
else {}
)
+1 -1
View File
@@ -7,5 +7,5 @@
// This script is intentionally loaded from index.html as a classic script,
// so we need to declare it as an entry point manually.
"entry": ["public/theme-init.js"]
"entry": ["public/theme-init.js"],
}
+828 -682
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -17,24 +17,24 @@
"test:unit": "vitest run"
},
"dependencies": {
"@tailwindcss/vite": "^4.2.4",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react-router-dom": "^7.15.0",
"@tailwindcss/vite": "^4.3.2",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-router-dom": "^7.18.1",
"socket.io-client": "^4.7.5"
},
"devDependencies": {
"@types/node": "^25.6.2",
"@types/react": "^19.2.14",
"@types/node": "^26.1.1",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
"knip": "^6.12.1",
"oxfmt": "^0.48.0",
"oxlint": "^1.63.0",
"oxlint-tsgolint": "^0.22.1",
"@vitejs/plugin-react": "^6.0.3",
"knip": "^6.26.0",
"oxfmt": "^0.58.0",
"oxlint": "^1.73.0",
"oxlint-tsgolint": "^0.24.0",
"tailwindcss": "^4.2.2",
"typescript": "^6.0.3",
"vite": "^8.0.11",
"vitest": "^4.1.5"
"vite": "^8.1.4",
"vitest": "^4.1.10"
}
}
+10 -3
View File
@@ -766,7 +766,8 @@ function App() {
(cfg.show_combined_selector ?? true) &&
getDefaultMode('ebook') !== 'blocked' &&
getDefaultMode('audiobook') !== 'blocked';
const nextEffectiveCombinedMode = combinedMode && nextCombinedModeAllowed;
const nextEffectiveCombinedMode =
nextCombinedModeAllowed && (combinedMode || cfg.force_combined_search);
const activeConfiguredProvider =
nextEffectiveCombinedMode && metadataProviderState.configured_provider_combined
? metadataProviderState.configured_provider_combined
@@ -864,7 +865,8 @@ function App() {
const audiobookMode = getDefaultMode('audiobook');
return ebookMode !== 'blocked' && audiobookMode !== 'blocked';
}, [effectiveSearchMode, config?.show_combined_selector, getDefaultMode]);
const effectiveCombinedMode = combinedMode && combinedModeAllowed;
const combinedModeLocked = combinedModeAllowed && config?.force_combined_search === true;
const effectiveCombinedMode = combinedModeAllowed && (combinedMode || combinedModeLocked);
const effectiveCombinedState = effectiveCombinedMode ? combinedState : null;
const defaultMetadataProviderForContentType =
@@ -1489,7 +1491,7 @@ function App() {
const handleCancel = async (id: string) => {
try {
await cancelDownload(id);
await fetchStatus();
await Promise.all([fetchStatus(), refreshActivitySnapshot()]);
} catch (error) {
console.error('Cancel failed:', error);
showToast('Failed to cancel/clear download', 'error');
@@ -2418,6 +2420,7 @@ function App() {
onContentTypeChange={setContentType}
allowedContentTypes={allowedContentTypes}
combinedMode={effectiveCombinedMode}
combinedModeLocked={combinedModeLocked}
onCombinedModeChange={combinedModeAllowed ? setCombinedMode : undefined}
queryTargets={queryTargets}
activeQueryTarget={effectiveActiveQueryTarget}
@@ -2499,6 +2502,7 @@ function App() {
onContentTypeChange={setContentType}
allowedContentTypes={allowedContentTypes}
combinedMode={effectiveCombinedMode}
combinedModeLocked={combinedModeLocked}
onCombinedModeChange={combinedModeAllowed ? setCombinedMode : undefined}
activeQueryField={activeQueryField}
searchMode={effectiveSearchMode}
@@ -2774,10 +2778,13 @@ function App() {
parsedParams={parsedParams}
config={config}
contentType={contentType}
combinedMode={combinedMode}
combinedModeAllowed={combinedModeAllowed}
advancedFilters={advancedFilters}
resolvedMetadataDefaultSort={resolvedMetadataDefaultSort}
resolvedMetadataSortOptions={resolvedMetadataSortOptions}
setContentType={setContentType}
setCombinedMode={setCombinedMode}
setSearchInput={setSearchInput}
setAdvancedFilters={setAdvancedFilters}
setShowAdvanced={setShowAdvanced}
@@ -58,6 +58,8 @@ const SEARCH_MODE_OPTIONS = [
},
];
const EMPTY_PROVIDERS: MetadataProviderSummary[] = [];
export const AdvancedFilters = ({
visible,
bookLanguages,
@@ -68,7 +70,7 @@ export const AdvancedFilters = ({
renderWrapper,
searchMode,
onSearchModeChange,
metadataProviders = [],
metadataProviders = EMPTY_PROVIDERS,
activeMetadataProvider,
onMetadataProviderChange,
contentType = 'ebook',
+5 -3
View File
@@ -1,5 +1,5 @@
import type { ReactNode } from 'react';
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import { useCallback, useId, useLayoutEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { useDismiss } from '../hooks/useDismiss';
@@ -55,6 +55,7 @@ export const Dropdown = ({
onOpenChange,
}: DropdownProps) => {
const [isOpen, setIsOpen] = useState(false);
const dropdownId = useId();
const containerRef = useRef<HTMLDivElement>(null);
const triggerRef = useRef<HTMLDivElement>(null);
const panelRef = useRef<HTMLDivElement>(null);
@@ -240,8 +241,8 @@ export const Dropdown = ({
<div className={widthClassName} ref={containerRef}>
{label && (
<label
className="mb-1.5 block text-xs font-medium text-gray-500 dark:text-gray-400"
onClick={toggleOpen}
htmlFor={dropdownId}
className="mb-1.5 block cursor-pointer text-xs font-medium text-gray-500 dark:text-gray-400"
>
{label}
</label>
@@ -251,6 +252,7 @@ export const Dropdown = ({
renderTrigger({ isOpen, toggle: toggleOpen })
) : (
<button
id={dropdownId}
type="button"
onClick={toggleOpen}
disabled={disabled}
@@ -147,6 +147,7 @@ export const DropdownList = ({
type="checkbox"
checked={selectedValues.includes(option.value)}
readOnly
aria-label={option.label}
className="pointer-events-none h-4 w-4 rounded-sm border-gray-300 text-sky-600 focus:ring-sky-500"
/>
)}
+20 -9
View File
@@ -62,6 +62,7 @@ interface HeaderProps {
onContentTypeChange?: (type: ContentType) => void;
allowedContentTypes?: ContentType[];
combinedMode?: boolean;
combinedModeLocked?: boolean;
onCombinedModeChange?: (enabled: boolean) => void;
queryTargets?: QueryTargetOption[];
activeQueryTarget?: string;
@@ -79,6 +80,15 @@ const applyTheme = (preference: string): void => {
document.documentElement.style.colorScheme = effective;
};
const DEFAULT_STATUS_COUNTS: ActivityStatusCounts = {
ongoing: 0,
completed: 0,
errored: 0,
pendingRequests: 0,
};
const EMPTY_ADMIN_USERS: ActingAsUserSelection[] = [];
const EMPTY_QUERY_TARGETS: QueryTargetOption[] = [];
export const Header = forwardRef<HeaderHandle, HeaderProps>(
(
{
@@ -98,7 +108,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
onSettingsClick,
isAdmin = false,
canAccessSettings,
statusCounts = { ongoing: 0, completed: 0, errored: 0, pendingRequests: 0 },
statusCounts = DEFAULT_STATUS_COUNTS,
onLogoClick,
authRequired = false,
isAuthenticated = false,
@@ -106,7 +116,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
displayName,
actingAsUser = null,
onActingAsUserChange,
adminUsers = [],
adminUsers = EMPTY_ADMIN_USERS,
isAdminUsersLoading = false,
adminUsersError = null,
hasLoadedAdminUsers = false,
@@ -118,8 +128,9 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
onContentTypeChange,
allowedContentTypes,
combinedMode,
combinedModeLocked,
onCombinedModeChange,
queryTargets = [],
queryTargets = EMPTY_QUERY_TARGETS,
activeQueryTarget = 'general',
onQueryTargetChange,
activeQueryField = null,
@@ -305,8 +316,8 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
// Determine if we should show icons only (both URLs configured)
const showIconsOnly = Boolean(calibreWebUrl && audiobookLibraryUrl);
// Icon buttons component - reused for both states
const IconButtons = () => (
// Icon buttons - reused for both states
const iconButtonsNode = (
<div className="flex items-center gap-2">
{/* Book Library Button */}
{calibreWebUrl && (
@@ -579,6 +590,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
onClick={handleLogout}
className="hover-action shrink-0 rounded-full p-2 text-red-600 transition-colors dark:text-red-400"
title="Sign Out"
aria-label="Sign Out"
>
<svg
className="h-5 w-5"
@@ -674,7 +686,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
/>
))}
<IconButtons />
{iconButtonsNode}
</div>
{/* Search bar - appear second on mobile (below logo+icons), first on desktop (left side) */}
@@ -711,6 +723,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
onContentTypeChange={onContentTypeChange}
allowedContentTypes={allowedContentTypes}
combinedMode={combinedMode}
combinedModeLocked={combinedModeLocked}
onCombinedModeChange={onCombinedModeChange}
queryTargets={queryTargets}
activeQueryTarget={activeQueryTarget}
@@ -723,9 +736,7 @@ export const Header = forwardRef<HeaderHandle, HeaderProps>(
{/* When search is NOT active: show icon buttons only on the right */}
{!showSearch && (
<div className="flex min-h-[48px] items-center justify-end">
<IconButtons />
</div>
<div className="flex min-h-[48px] items-center justify-end">{iconButtonsNode}</div>
)}
</div>
</header>
@@ -101,6 +101,7 @@ const PasswordLoginForm = ({
type="text"
id="username"
name="username"
aria-label="Username"
autoComplete="username"
autoCapitalize="none"
autoCorrect="off"
@@ -131,6 +132,7 @@ const PasswordLoginForm = ({
type={showPassword ? 'text' : 'password'}
id="password"
name="password"
aria-label="Password"
autoComplete="current-password"
autoCapitalize="none"
autoCorrect="off"
@@ -168,6 +170,7 @@ const PasswordLoginForm = ({
checked={rememberMe}
onChange={(event) => setRememberMe(event.target.checked)}
disabled={isLoading}
aria-label="Remember me for 7 days"
className="h-4 w-4 rounded-sm accent-sky-900 focus:ring-2 focus:ring-sky-500 disabled:cursor-not-allowed disabled:opacity-50"
style={{ borderColor: 'var(--border-color)' }}
/>
+4 -1
View File
@@ -729,6 +729,8 @@ function ErrorState({ message }: { message: string }) {
);
}
const EMPTY_SUPPORTED_AUDIOBOOK_FORMATS: string[] = [];
const ReleaseModalSession = ({
book,
onClose,
@@ -737,7 +739,7 @@ const ReleaseModalSession = ({
onRequestBook,
getPolicyModeForSource,
supportedFormats,
supportedAudiobookFormats = [],
supportedAudiobookFormats = EMPTY_SUPPORTED_AUDIOBOOK_FORMATS,
contentType,
defaultLanguages,
bookLanguages,
@@ -2094,6 +2096,7 @@ const ReleaseModalSession = ({
value={manualQuery}
onChange={(e) => setManualQuery(e.target.value)}
placeholder="Type a custom search query (overrides all sources)"
aria-label="Custom search query"
className="w-full rounded-lg border border-(--border-muted) bg-(--bg) px-3 py-2 text-sm text-(--text)"
/>
<button
@@ -64,9 +64,11 @@ const getRequestConfirmationSessionKey = (payload: CreateRequestPayload): string
].join('|');
};
const EMPTY_PAYLOADS: CreateRequestPayload[] = [];
export function RequestConfirmationModal({
payload,
extraPayloads = [],
extraPayloads = EMPTY_PAYLOADS,
allowNotes,
onConfirm,
onClose,
@@ -89,7 +91,7 @@ export function RequestConfirmationModal({
function RequestConfirmationModalSession({
payload,
extraPayloads = [],
extraPayloads = EMPTY_PAYLOADS,
allowNotes,
onConfirm,
onClose,
@@ -305,6 +307,7 @@ function RequestConfirmationModalSession({
</label>
<textarea
id="request-note"
aria-label="Note (optional)"
value={note}
onChange={(event) => setNote(truncateRequestNote(event.target.value))}
maxLength={MAX_REQUEST_NOTE_LENGTH}
+18 -6
View File
@@ -34,6 +34,7 @@ interface SearchBarProps {
onContentTypeChange?: (type: ContentType) => void;
allowedContentTypes?: ContentType[];
combinedMode?: boolean;
combinedModeLocked?: boolean;
onCombinedModeChange?: (enabled: boolean) => void;
queryTargets?: QueryTargetOption[];
activeQueryTarget?: string;
@@ -48,6 +49,7 @@ export interface SearchBarHandle {
const EMPTY_SORT_OPTIONS: SortOption[] = [];
const EMPTY_AUTOCOMPLETE_OPTIONS: DynamicFieldOption[] = [];
const EMPTY_QUERY_TARGETS: QueryTargetOption[] = [];
const BookIcon = () => (
<svg
@@ -180,8 +182,9 @@ export const SearchBar = forwardRef<SearchBarHandle, SearchBarProps>(
onContentTypeChange,
allowedContentTypes,
combinedMode = false,
combinedModeLocked = false,
onCombinedModeChange,
queryTargets = [],
queryTargets = EMPTY_QUERY_TARGETS,
activeQueryTarget = 'general',
onQueryTargetChange,
activeQueryField,
@@ -518,6 +521,7 @@ export const SearchBar = forwardRef<SearchBarHandle, SearchBarProps>(
type="checkbox"
checked={Boolean(value)}
onChange={(e) => onChange(e.target.checked)}
aria-label={activeQueryField.label}
className="h-4 w-4 rounded-sm border-(--border-muted) text-emerald-500 focus:ring-emerald-500/50"
/>
<span className="truncate text-sm" style={{ color: 'var(--text)' }}>
@@ -796,11 +800,19 @@ export const SearchBar = forwardRef<SearchBarHandle, SearchBarProps>(
stroke="currentColor"
aria-hidden="true"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
/>
{combinedModeLocked ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244"
/>
)}
</svg>
</div>
</div>
@@ -32,6 +32,7 @@ interface SearchSectionProps {
onContentTypeChange?: (type: ContentType) => void;
allowedContentTypes?: ContentType[];
combinedMode?: boolean;
combinedModeLocked?: boolean;
onCombinedModeChange?: (enabled: boolean) => void;
activeQueryField?: MetadataSearchField | null;
searchMode: SearchMode;
@@ -64,6 +65,7 @@ export const SearchSection = ({
onContentTypeChange,
allowedContentTypes,
combinedMode,
combinedModeLocked,
onCombinedModeChange,
activeQueryField,
searchMode,
@@ -105,6 +107,7 @@ export const SearchSection = ({
onContentTypeChange={onContentTypeChange}
allowedContentTypes={allowedContentTypes}
combinedMode={combinedMode}
combinedModeLocked={combinedModeLocked}
onCombinedModeChange={onCombinedModeChange}
queryTargets={queryTargets}
activeQueryTarget={activeQueryTarget}
@@ -12,10 +12,13 @@ interface UrlSearchBootstrapMountProps {
parsedParams: ParsedUrlSearch;
config: AppConfig;
contentType: ContentType;
combinedMode: boolean;
combinedModeAllowed: boolean;
advancedFilters: AdvancedFilterState;
resolvedMetadataDefaultSort: string;
resolvedMetadataSortOptions: SortOption[];
setContentType: (value: ContentType) => void;
setCombinedMode: (value: boolean) => void;
setSearchInput: (value: string) => void;
setAdvancedFilters: Dispatch<SetStateAction<AdvancedFilterState>>;
setShowAdvanced: (value: boolean) => void;
@@ -32,10 +35,13 @@ export const UrlSearchBootstrapMount = ({
parsedParams,
config,
contentType,
combinedMode,
combinedModeAllowed,
advancedFilters,
resolvedMetadataDefaultSort,
resolvedMetadataSortOptions,
setContentType,
setCombinedMode,
setSearchInput,
setAdvancedFilters,
setShowAdvanced,
@@ -49,11 +55,19 @@ export const UrlSearchBootstrapMount = ({
const parsedSearchMode = config.search_mode || 'universal';
const urlContentTypeOverride =
parsedSearchMode === 'universal' ? parsedParams.contentType : undefined;
const urlForcesCombined =
parsedSearchMode === 'universal' && parsedParams.combinedMode === true && combinedModeAllowed;
if (urlContentTypeOverride && urlContentTypeOverride !== contentType) {
setContentType(urlContentTypeOverride);
}
if (urlForcesCombined && !combinedMode) {
setCombinedMode(true);
} else if (urlContentTypeOverride && combinedMode) {
setCombinedMode(false);
}
if (!parsedParams.hasSearchParams) {
return;
}
@@ -436,6 +436,7 @@ const RejectInlinePanel = ({
Reject request for <span className="opacity-80">{itemTitle || 'Untitled request'}</span>
</p>
<textarea
aria-label="Optional note shown to the user"
value={rejectNote}
onChange={(event) => setRejectNote(event.target.value.slice(0, MAX_ADMIN_NOTE_LENGTH))}
rows={3}
@@ -225,6 +225,9 @@ const getInitialPinnedPreference = (): boolean => {
}
};
const EMPTY_KEYS: string[] = [];
const EMPTY_ITEMS: ActivityItem[] = [];
export const ActivitySidebar = ({
isOpen,
onClose,
@@ -235,8 +238,8 @@ export const ActivitySidebar = ({
onRetry,
onDownloadDismiss,
requestItems,
dismissedItemKeys = [],
historyItems = [],
dismissedItemKeys = EMPTY_KEYS,
historyItems = EMPTY_ITEMS,
historyLoaded = false,
historyHasMore = false,
historyLoading = false,
@@ -67,6 +67,7 @@ export const CardView = ({
};
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- mouse handlers drive a decorative hover shadow only; no interactive behavior requiring keyboard support
<article
className="book-card space-between animate-pop-up relative flex h-full w-full flex-col transition-shadow duration-300 max-sm:h-[180px] max-sm:flex-row sm:max-w-[292px] sm:flex-col"
style={{
@@ -70,6 +70,7 @@ export const CompactView = ({
};
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- mouse handlers drive a decorative hover shadow only; no interactive behavior requiring keyboard support
<article
className="book-card animate-pop-up relative flex! h-[180px]! w-full flex-row! transition-shadow duration-300"
style={{
@@ -21,7 +21,6 @@ import {
normalizeUserOverrideSections,
UserOverridesSections,
} from './users';
import type { PerUserSettings } from './users/types';
import { UserAccountCardContent, UserEditActions, UserIdentityHeader } from './users/UserCard';
import { useUserOverridesState } from './users/useUserOverridesState';
@@ -153,7 +152,7 @@ const SelfSettingsModalSession = ({
normalizeUserOverrideSections(context.visibleUserSettingsSections, 'self'),
);
applyUserOverridesContext({
settings: (context.user.settings || {}) as PerUserSettings,
settings: context.user.settings || {},
userOverridableKeys: context.userOverridableKeys || [],
});
setEditPassword('');
@@ -102,6 +102,7 @@ export const NamingTemplateField = ({
value={value}
onChange={(event) => onChange(boundField.key, event.target.value)}
placeholder={boundField.placeholder}
aria-label={boundField.placeholder || 'Naming Template'}
maxLength={boundField.maxLength}
disabled={fieldDisabled}
className="w-full rounded-lg border border-(--border-muted) bg-(--bg-soft) px-3 py-2 text-sm transition-colors focus:border-sky-500 focus:ring-2 focus:ring-sky-500/50 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-60"
@@ -19,6 +19,7 @@ export const NumberField = ({ field, value, onChange, disabled }: NumberFieldPro
min={field.min}
max={field.max}
step={field.step ?? 1}
aria-label={field.label || 'Number field'}
disabled={isDisabled}
className="w-full rounded-lg border border-(--border-muted) bg-(--bg-soft) px-3 py-2 text-sm transition-colors focus:border-sky-500 focus:ring-2 focus:ring-sky-500/50 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-60"
/>
@@ -21,6 +21,7 @@ export const PasswordField = ({ field, value, onChange, disabled }: PasswordFiel
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder={field.placeholder}
aria-label={field.label || field.placeholder || 'Password field'}
disabled={isDisabled}
className="w-full rounded-lg border border-(--border-muted) bg-(--bg-soft) px-3 py-2 pr-10 text-sm transition-colors focus:border-sky-500 focus:ring-2 focus:ring-sky-500/50 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-60"
/>
@@ -277,6 +277,7 @@ export const TableField = ({ field, value, onChange, disabled }: TableFieldProps
checked={Boolean(cellValue)}
onChange={(e) => updateCell(rowIndex, col.key, e.target.checked)}
disabled={isDisabled}
aria-label={`${col.label || col.key} row ${rowIndex + 1}`}
className="h-4 w-4 rounded border-gray-300 text-sky-600 focus:ring-sky-500 disabled:cursor-not-allowed disabled:opacity-60"
/>
</div>
@@ -361,6 +362,7 @@ export const TableField = ({ field, value, onChange, disabled }: TableFieldProps
value={toPrimitiveString(cellValue)}
onChange={(e) => updateCell(rowIndex, col.key, e.target.value)}
placeholder={col.placeholder}
aria-label={`${col.label || col.key} row ${rowIndex + 1}`}
disabled={isDisabled}
className="w-full rounded-lg border border-(--border-muted) bg-(--bg-soft) px-3 py-2 text-sm transition-colors focus:border-sky-500 focus:ring-2 focus:ring-sky-500/50 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-60"
/>
@@ -143,6 +143,7 @@ export const TagListField = ({
type="text"
value={draft}
onChange={(e) => setDraft(e.target.value)}
aria-label={field.label || field.placeholder || 'Add item'}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -17,6 +17,7 @@ export const TextField = ({ field, value, onChange, disabled }: TextFieldProps)
value={value ?? ''}
onChange={(e) => onChange(e.target.value)}
placeholder={field.placeholder}
aria-label={field.label || field.placeholder || 'Text field'}
maxLength={field.maxLength}
disabled={isDisabled}
className="w-full rounded-lg border border-(--border-muted) bg-(--bg-soft) px-3 py-2 text-sm transition-colors focus:border-sky-500 focus:ring-2 focus:ring-sky-500/50 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-60"
@@ -139,9 +139,11 @@ function formatUserOverrideValue(value: unknown): string {
}
}
const EMPTY_DETAILS: Array<{ userId: number; username: string; value: unknown }> = [];
const UserOverriddenBadge = ({
count,
details = [],
details = EMPTY_DETAILS,
}: {
count: number;
details?: Array<{ userId: number; username: string; value: unknown }>;
@@ -60,6 +60,8 @@ const modeDescriptions: Record<RequestPolicyMode, string> = {
blocked: 'Downloads and requests are blocked.',
};
const EMPTY_BASE_RULES: RequestPolicyRuleRow[] = [];
export const RequestPolicyGrid = ({
defaultModes,
onDefaultModeChange,
@@ -67,7 +69,7 @@ export const RequestPolicyGrid = ({
defaultModeOverrides,
defaultModeDisabled,
explicitRules,
baseRules = [],
baseRules = EMPTY_BASE_RULES,
onExplicitRulesChange,
sourceCapabilities,
rulesDisabled = false,
@@ -3,6 +3,7 @@ interface ToggleSwitchProps {
onChange: (checked: boolean) => void;
disabled?: boolean;
color?: 'sky' | 'emerald';
ariaLabel?: string;
}
const colorClasses = {
@@ -15,6 +16,7 @@ export const ToggleSwitch = ({
onChange,
disabled = false,
color = 'sky',
ariaLabel = 'Toggle switch',
}: ToggleSwitchProps) => {
const { active, ring } = colorClasses[color];
@@ -23,6 +25,7 @@ export const ToggleSwitch = ({
type="button"
role="switch"
aria-checked={checked}
aria-label={ariaLabel}
onClick={() => !disabled && onChange(!checked)}
disabled={disabled}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 focus:ring-2 focus:outline-hidden ${ring} disabled:cursor-not-allowed disabled:opacity-60 ${checked ? active : 'bg-gray-300 dark:bg-gray-600'}`}
@@ -188,6 +188,7 @@ export function Tooltip({
isVisible &&
coords &&
createPortal(
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- interactive tooltip stays open while hovered; keyboard users are served by focus handlers on the trigger element
<div
ref={tooltipRef}
role="tooltip"
+1 -1
View File
@@ -41,7 +41,7 @@ export function useUrlSearch({ enabled }: UseUrlSearchOptions): UseUrlSearchRetu
}
const parsed = parseUrlSearchParams(searchParams);
return parsed.hasSearchParams || parsed.contentType ? parsed : null;
return parsed.hasSearchParams || parsed.contentType || parsed.combinedMode ? parsed : null;
}, [enabled, searchParams]);
return {
+4 -4
View File
@@ -146,7 +146,7 @@ export const useUsersFetch = ({ onShowToast }: UseUsersFetchParams) => {
if (fullUser.settings) {
userSettings = {
...fullUser.settings,
} as PerUserSettings;
};
}
const userOverridableSettings = new Set<string>();
@@ -162,7 +162,7 @@ export const useUsersFetch = ({ onShowToast }: UseUsersFetchParams) => {
userSettings = {
...userSettings,
...deliveryResult.value.userOverrides,
} as PerUserSettings;
};
}
deliveryResult.value.keys.forEach((key) => userOverridableSettings.add(key));
}
@@ -173,7 +173,7 @@ export const useUsersFetch = ({ onShowToast }: UseUsersFetchParams) => {
userSettings = {
...userSettings,
...searchResult.value.userOverrides,
} as PerUserSettings;
};
}
searchResult.value.keys.forEach((key) => userOverridableSettings.add(key));
}
@@ -184,7 +184,7 @@ export const useUsersFetch = ({ onShowToast }: UseUsersFetchParams) => {
userSettings = {
...userSettings,
...notificationResult.value.userOverrides,
} as PerUserSettings;
};
}
notificationResult.value.keys.forEach((key) => userOverridableSettings.add(key));
}
@@ -42,4 +42,22 @@ describe('parseUrlSearchParams', () => {
expect(parsed.hasSearchParams).toBe(false);
expect(parsed.contentType).toBe('ebook');
});
it('parses content_type=combined as a combined-mode override', () => {
const parsed = parseUrlSearchParams(new URLSearchParams('q=dune&content_type=combined'));
expect(parsed.searchInput).toBe('dune');
expect(parsed.hasSearchParams).toBe(true);
expect(parsed.contentType).toBe(undefined);
expect(parsed.combinedMode).toBe(true);
});
it('keeps combined-only links from auto-triggering a blank search', () => {
const parsed = parseUrlSearchParams(new URLSearchParams('content_type=combined'));
expect(parsed.searchInput).toBe('');
expect(parsed.hasSearchParams).toBe(false);
expect(parsed.contentType).toBe(undefined);
expect(parsed.combinedMode).toBe(true);
});
});
+1
View File
@@ -280,6 +280,7 @@ export interface AppConfig {
default_release_source_audiobook?: string; // Default tab in ReleaseModal for audiobooks
show_release_source_links: boolean;
show_combined_selector: boolean;
force_combined_search: boolean;
books_output_mode: BooksOutputMode;
auto_open_downloads_sidebar: boolean; // Auto-open sidebar when download is queued
hardcover_auto_remove_on_download: boolean; // Auto-remove from active Hardcover list on download
+15 -7
View File
@@ -7,18 +7,24 @@ export interface ParsedUrlSearch {
searchInput: string;
advancedFilters: Partial<AdvancedFilterState>;
contentType?: ContentType;
combinedMode?: boolean;
hasSearchParams: boolean;
}
const parseContentType = (value: string | null): ContentType | undefined => {
const parseContentTypeParam = (
value: string | null,
): { contentType?: ContentType; combinedMode?: true } => {
if (!value) {
return undefined;
return {};
}
const normalized = value.trim().toLowerCase();
if (normalized === 'ebook' || normalized === 'audiobook') {
return normalized;
return { contentType: normalized };
}
return undefined;
if (normalized === 'combined') {
return { combinedMode: true };
}
return {};
};
/**
@@ -26,21 +32,23 @@ const parseContentType = (value: string | null): ContentType | undefined => {
*
* Supports both Direct Download and Universal mode parameters.
* In Universal mode, query/sort are used for search text, and content_type
* is used to select ebook vs audiobook.
* selects ebook, audiobook, or combined (search both at once).
*
* @example
* // Direct mode: /?q=harry+potter&author=rowling&format=epub&lang=en
* // Universal mode: /?q=dune&sort=popularity
* // Universal combined: /?q=dune&content_type=combined
*/
export function parseUrlSearchParams(searchParams: URLSearchParams): ParsedUrlSearch {
const parsedContentType = parseContentType(
const contentTypeParam = parseContentTypeParam(
searchParams.get('content_type') || searchParams.get('contentType'),
);
const result: ParsedUrlSearch = {
searchInput: '',
advancedFilters: {},
contentType: parsedContentType,
contentType: contentTypeParam.contentType,
combinedMode: contentTypeParam.combinedMode,
hasSearchParams: false,
};
+5 -5
View File
@@ -58,7 +58,7 @@ SAMPLE_DETAIL_HTML = """
<table>
<tr>
<td>Info Hash</td>
<td>ABC123DEF456GHI789JKL012MNO345PQR678STU</td>
<td>ABC123DEF456789012345678901234567890ABCD</td>
</tr>
<tr>
<td>Tracker 1</td>
@@ -83,7 +83,7 @@ DETAIL_HTML_NO_TRACKERS = """
<table>
<tr>
<td>Info Hash</td>
<td>ABC123DEF456GHI789JKL012MNO345PQR678STU</td>
<td>ABC123DEF456789012345678901234567890ABCD</td>
</tr>
</table>
</body>
@@ -360,7 +360,7 @@ class TestExtractMagnetLink:
assert magnet_link is not None
assert magnet_link.startswith("magnet:?xt=urn:btih:")
assert "ABC123DEF456GHI789JKL012MNO345PQR678STU" in magnet_link
assert "ABC123DEF456789012345678901234567890ABCD" in magnet_link
assert "udp%3A//tracker.openbittorrent.com%3A80" in magnet_link
assert "http%3A//tracker.example.com%3A8080" in magnet_link
assert mock_html_get.call_count == 2
@@ -395,7 +395,7 @@ class TestExtractMagnetLink:
assert magnet_link is not None
assert magnet_link.startswith("magnet:?xt=urn:btih:")
assert "ABC123DEF456GHI789JKL012MNO345PQR678STU" in magnet_link
assert "ABC123DEF456789012345678901234567890ABCD" in magnet_link
# Should contain default trackers
assert "udp%3A//tracker.openbittorrent.com%3A80" in magnet_link
@@ -441,7 +441,7 @@ class TestExtractMagnetLink:
<table>
<tr>
<td>Info Hash</td>
<td>ABC 123 DEF 456</td>
<td>ABC 123 DEF 456 789 012 345 678 901 234 567 890 ABC D</td>
</tr>
</table>
</body>
+103
View File
@@ -0,0 +1,103 @@
"""Cluster 7 (audiobook/ABB) parse-contract guards.
ABB forces ``https://`` for search and detail fetches, so it can't be exercised
hermetically in the HTTP e2e docker platform. Its recurring bugs are instead in
*parsing*: magnet/info-hash extraction ("Fix ABB magnet parsing", and the
qbittorrent hash-length issue #386) and DOM/layout drift. These contract tests
feed golden HTML through the real scraper — the same fail-on-drift philosophy as
the AA layout-drift guard — and run in normal CI.
They deliberately cover cases the existing ``test_scraper.py`` does not: info-hash
*normalization* (whitespace/case), the in-page magnet *fallback*, and a layout
drift that must degrade to an empty result rather than crash.
"""
from __future__ import annotations
import re
from unittest.mock import patch
from shelfmark.release_sources.audiobookbay import scraper
# Detail page where the Info Hash is lowercase and split by whitespace/newlines —
# the exact shape that produced malformed magnets / wrong hash lengths (#386).
DETAIL_HTML_MESSY_HASH = """
<html><body><table>
<tr><td>Info Hash</td><td>abc123def456789012345678
901234567890abcd</td></tr>
<tr><td>Tracker 1</td><td>udp://tracker.openbittorrent.com:80</td></tr>
</table></body></html>
"""
# Info Hash cell is junk, but a full magnet link is posted elsewhere on the page.
DETAIL_HTML_MAGNET_FALLBACK = """
<html><body>
<table><tr><td>Info Hash</td><td>n/a</td></tr></table>
<p>Mirror: magnet:?xt=urn:btih:1111111111111111111111111111111111111111&dn=x</p>
</body></html>
"""
# DOM drift: results are present but the .post / .postTitle structure changed.
SEARCH_HTML_LAYOUT_DRIFT = """
<html><body>
<article class="result-card">
<header><a href="/abss/drifted/">Drifted Audiobook - Author</a></header>
<span class="lang">English</span>
</article>
</body></html>
"""
def _patch_detail(html: str):
return patch(
"shelfmark.release_sources.audiobookbay.scraper.downloader.html_get_page",
return_value=html,
)
def test_info_hash_is_normalized_to_canonical_btih() -> None:
"""Whitespace/newlines are stripped and the hash upper-cased to a valid
40-char btih (regression for #386 / 'Fix ABB magnet parsing')."""
with _patch_detail(DETAIL_HTML_MESSY_HASH):
magnet = scraper.extract_magnet_link("https://audiobookbay.lu/abss/x/", "audiobookbay.lu")
assert magnet is not None, "messy-but-valid info hash should still yield a magnet"
btih = re.search(r"xt=urn:btih:([0-9A-Fa-f]+)", magnet)
assert btih is not None, magnet
assert btih.group(1) == "ABC123DEF456789012345678901234567890ABCD"
assert len(btih.group(1)) == 40
assert "tr=" in magnet # tracker carried through
def test_magnet_fallback_when_info_hash_cell_is_junk() -> None:
"""When the Info Hash cell is invalid, the scraper recovers the hash from an
in-page magnet link rather than failing."""
with _patch_detail(DETAIL_HTML_MAGNET_FALLBACK):
magnet = scraper.extract_magnet_link("https://audiobookbay.lu/abss/y/", "audiobookbay.lu")
assert magnet is not None
assert "btih:1111111111111111111111111111111111111111" in magnet
def test_missing_info_hash_returns_none_not_crash() -> None:
"""No hash anywhere -> None (clean failure), never an exception."""
with _patch_detail("<html><body><p>nothing here</p></body></html>"):
assert (
scraper.extract_magnet_link("https://audiobookbay.lu/abss/z/", "audiobookbay.lu")
is None
)
def test_search_layout_drift_degrades_to_empty() -> None:
"""A changed results DOM yields zero parsed results without raising — the
ABB analogue of the AA layout-drift guard."""
with (
patch(
"shelfmark.release_sources.audiobookbay.scraper.downloader.html_get_page",
return_value=(SEARCH_HTML_LAYOUT_DRIFT, "https://audiobookbay.lu/?s=test"),
),
patch(
"shelfmark.release_sources.audiobookbay.scraper.config.get",
return_value=0.0,
),
):
results = scraper.search_audiobookbay("test", max_pages=1, hostname="audiobookbay.lu")
assert results == [], f"drifted DOM should parse to no results, got {results!r}"
+69
View File
@@ -274,6 +274,75 @@ def test_run_child_process_writes_failure_for_unexpected_exception(monkeypatch,
assert "plain SeleniumBase startup failure" in result["traceback"]
def test_run_child_process_applies_parent_dns_config(monkeypatch, tmp_path):
"""Regression test for issue #1028: the helper subprocess must mirror the parent's
DNS provider, otherwise it pre-resolves AA hostnames against (possibly hijacked)
system DNS and Chrome loads the wrong page."""
import io
import json
import shelfmark.bypass.internal_bypasser as internal_bypasser
result_path = tmp_path / "result.json"
request = {
"url": "https://annas-archive.pk/slow_download/abc/0/0",
"retry": 1,
"result_path": str(result_path),
"dns_config": {
"provider": "cloudflare",
"servers": ["1.1.1.1", "1.0.0.1"],
"doh_url": "https://cloudflare-dns.com/dns-query",
"doh_enabled": True,
"is_auto_mode": True,
},
}
applied: list[tuple] = []
monkeypatch.setattr(
internal_bypasser.network,
"set_dns_provider",
lambda provider, manual=None, *, use_doh=None: applied.append((provider, manual, use_doh)),
)
monkeypatch.setattr(internal_bypasser, "get", lambda *_a, **_k: "<html>ok</html>")
monkeypatch.setattr(internal_bypasser.sys, "stdin", io.StringIO(json.dumps(request)))
assert internal_bypasser._run_child_process() == 0
assert applied == [("cloudflare", None, True)]
def test_apply_parent_dns_config_skips_auto_and_empty(monkeypatch):
import shelfmark.bypass.internal_bypasser as internal_bypasser
calls: list = []
monkeypatch.setattr(
internal_bypasser.network,
"set_dns_provider",
lambda *a, **k: calls.append((a, k)),
)
internal_bypasser._apply_parent_dns_config({"provider": "auto"})
internal_bypasser._apply_parent_dns_config({})
assert calls == []
def test_apply_parent_dns_config_forwards_manual_servers(monkeypatch):
import shelfmark.bypass.internal_bypasser as internal_bypasser
calls: list = []
monkeypatch.setattr(
internal_bypasser.network,
"set_dns_provider",
lambda provider, manual=None, *, use_doh=None: calls.append((provider, manual, use_doh)),
)
internal_bypasser._apply_parent_dns_config(
{"provider": "manual", "servers": ["9.9.9.9"], "doh_enabled": False}
)
assert calls == [("manual", ["9.9.9.9"], False)]
def test_prepare_child_browser_env_uses_writable_runtime_paths(monkeypatch, tmp_path):
import stat
+14
View File
@@ -368,6 +368,20 @@ def test_download_source_settings_include_direct_download_toggle():
assert "Add your own mirror URLs" in toggle_field.description
def test_download_source_settings_include_distant_path_language_toggle():
from shelfmark.config.settings import download_source_settings
fields = download_source_settings()
toggle_field = next(
field
for field in fields
if getattr(field, "key", None) == "DIRECT_DOWNLOAD_LANGUAGE_FROM_PATH"
)
assert toggle_field.default is False
assert "distant path" in toggle_field.description.lower()
def test_fast_source_options_lock_entries_without_mirror_or_donator_requirements(monkeypatch):
from shelfmark.config.settings import _get_fast_source_options
+116
View File
@@ -257,3 +257,119 @@ def test_entrypoint_root_bootstrap_fails_closed_when_config_repair_fails(tmp_pat
assert f"Configured runtime identity: {os.getuid()}:{os.getgid()}" in result.stdout
assert f"chown -R {os.getuid()}:{os.getgid()} /path/to/config" in result.stdout
assert "Startup mode: root" not in result.stdout
def test_entrypoint_rejects_wireguard_in_non_root_mode(tmp_path):
result, _, _, _ = _run_entrypoint(tmp_path, extra_env={"USING_WIREGUARD": "true"})
assert result.returncode == 1
assert "USING_WIREGUARD=true requires the container to start as root." in result.stderr
assert "Non-root mode skips the privileged network setup WireGuard depends on." in result.stderr
def test_entrypoint_rejects_tor_and_wireguard_together(tmp_path):
result, _, _, _ = _run_entrypoint(
tmp_path,
extra_env={"USING_TOR": "true", "USING_WIREGUARD": "true"},
)
assert result.returncode == 1
assert (
"USING_TOR and USING_WIREGUARD are mutually exclusive; enable only one egress mode."
in result.stderr
)
# The mutual-exclusion check must fire before either egress script runs, so
# neither the Tor nor the WireGuard privileged-setup errors should appear.
assert "requires the container to start as root" not in result.stderr
def test_entrypoint_mutual_exclusion_precedes_tor_startup(tmp_path):
# Even in root mode, enabling both must fail fast on mutual exclusion rather
# than starting tor.sh and then aborting.
result, _, _, _ = _run_entrypoint(
tmp_path,
simulate_root_startup=True,
extra_env={"USING_TOR": "true", "USING_WIREGUARD": "true"},
)
assert result.returncode == 1
assert (
"USING_TOR and USING_WIREGUARD are mutually exclusive; enable only one egress mode."
in result.stderr
)
def test_entrypoint_aborts_before_gunicorn_when_wireguard_fails(tmp_path):
"""Security invariant: if wireguard.sh exits non-zero (any fail-closed path),
entrypoint.sh must abort under `set -e` so gunicorn NEVER starts. A booting
app after a failed egress setup would be a kill-switch bypass / IP leak.
"""
# Run the REAL entrypoint from a temp cwd that provides a stub `./wireguard.sh`
# which exits 1, plus a stub `./tor.sh` (unused here) for completeness.
work = tmp_path / "work"
work.mkdir()
real_entrypoint = ENTRYPOINT_PATH.read_text()
(work / "entrypoint.sh").write_text(real_entrypoint)
(work / "entrypoint.sh").chmod(0o755)
_write_executable(
work / "wireguard.sh",
"#!/bin/sh\necho 'stub wireguard.sh failing closed' >&2\nexit 1\n",
)
_write_executable(work / "tor.sh", "#!/bin/sh\nexit 0\n")
bin_dir, runtime_home_file, runtime_args_file = _build_stub_bin(tmp_path)
config_dir = tmp_path / "config"
config_dir.mkdir(exist_ok=True)
env = os.environ.copy()
env.update(
{
"BUILD_VERSION": "test-build",
"CONFIG_DIR": str(config_dir),
"DEBUG": "false",
"ENABLE_LOGGING": "false",
"ENTRYPOINT_GUNICORN_ARGS_FILE": str(runtime_args_file),
"ENTRYPOINT_GUNICORN_HOME_FILE": str(runtime_home_file),
"ENTRYPOINT_REAL_ID": ID_PATH,
"ENTRYPOINT_REAL_MKDIR": MKDIR_PATH,
"ENTRYPOINT_REAL_STAT": STAT_PATH,
"ENTRYPOINT_STUB_GID": str(os.getgid()),
"ENTRYPOINT_STUB_HOME": str(tmp_path / "runtime-home"),
"ENTRYPOINT_STUB_UID": str(os.getuid()),
# Root startup so the WireGuard branch runs ./wireguard.sh (our stub).
"ENTRYPOINT_STUB_CURRENT_GID": "0",
"ENTRYPOINT_STUB_CURRENT_UID": "0",
"ENTRYPOINT_STUB_STAT_OWNER": "0:0",
"FLASK_PORT": "8084",
"LOG_LEVEL": "info",
"LOG_ROOT": str(tmp_path / "logs"),
"PATH": f"{bin_dir}:{env.get('PATH', '')}",
"PGID": str(os.getgid()),
"PUID": str(os.getuid()),
"RELEASE_VERSION": "test-release",
"TMP_DIR": str(tmp_path / "tmp"),
"TZ": "",
"USING_EXTERNAL_BYPASSER": "true",
"USING_WIREGUARD": "true",
}
)
with _entrypoint_lock():
result = subprocess.run(
[BASH_PATH, str(work / "entrypoint.sh")],
capture_output=True,
cwd=work,
env=env,
text=True,
check=False,
)
# Entrypoint must have aborted with the stub's non-zero status...
assert result.returncode != 0
# ...the failure must actually come from wireguard.sh (not some unrelated
# earlier abort), proven by the stub's marker on stderr...
assert "stub wireguard.sh failing closed" in result.stderr
# ...and gunicorn must NEVER have been invoked (args file never written).
assert not runtime_args_file.exists(), (
"gunicorn was started despite wireguard.sh failing — kill-switch bypass!"
)
+9
View File
@@ -507,6 +507,15 @@ class TestConcurrencyConfiguration:
assert interval >= 1
assert interval <= 10
def test_completed_path_timeout_default(self):
"""Completed external-client path wait should default to the legacy grace period."""
from shelfmark.core.config import config
config.refresh()
timeout = config.get("DOWNLOAD_CLIENT_COMPLETED_PATH_TIMEOUT", 60)
assert timeout == 60
# =============================================================================
# Cache Configuration Tests
+82
View File
@@ -0,0 +1,82 @@
"""Tests for the OIDC Test Connection handler."""
from unittest.mock import MagicMock, patch
from shelfmark.config.security_handlers import check_oidc_connection
DISCOVERY_URL = "https://auth.example.com/.well-known/openid-configuration"
DISCOVERY_DOCUMENT = {
"issuer": "https://auth.example.com",
"authorization_endpoint": "https://auth.example.com/authorize",
"token_endpoint": "https://auth.example.com/token",
"jwks_uri": "https://auth.example.com/jwks",
}
def _mock_response(payload):
response = MagicMock()
response.json.return_value = payload
response.raise_for_status.return_value = None
return response
def _run_check(responses):
"""Run check_oidc_connection with requests.get returning the given responses."""
with (
patch("requests.get", side_effect=responses) as mock_get,
patch("shelfmark.config.security_handlers.get_ssl_verify", return_value=True),
):
result = check_oidc_connection(
load_security_config=lambda: {"OIDC_DISCOVERY_URL": DISCOVERY_URL},
current_values={},
logger=MagicMock(),
)
return result, mock_get
class TestCheckOIDCConnection:
def test_succeeds_when_discovery_and_jwks_are_valid(self):
responses = [
_mock_response(DISCOVERY_DOCUMENT),
_mock_response({"keys": [{"kty": "RSA", "kid": "abc"}]}),
]
result, mock_get = _run_check(responses)
assert result["success"] is True
assert "Connected to" in result["message"]
jwks_call = mock_get.call_args_list[1]
assert jwks_call.args[0] == DISCOVERY_DOCUMENT["jwks_uri"]
def test_fails_with_signing_key_guidance_when_jwks_is_empty(self):
responses = [
_mock_response(DISCOVERY_DOCUMENT),
_mock_response({}),
]
result, _ = _run_check(responses)
assert result["success"] is False
assert "no token signing keys" in result["message"]
assert "Signing Key" in result["message"]
def test_fails_with_signing_key_guidance_when_jwks_keys_list_is_empty(self):
responses = [
_mock_response(DISCOVERY_DOCUMENT),
_mock_response({"keys": []}),
]
result, _ = _run_check(responses)
assert result["success"] is False
assert "no token signing keys" in result["message"]
def test_fails_when_discovery_document_missing_jwks_uri(self):
document = {k: v for k, v in DISCOVERY_DOCUMENT.items() if k != "jwks_uri"}
responses = [_mock_response(document)]
result, _ = _run_check(responses)
assert result["success"] is False
assert "jwks_uri" in result["message"]
def test_fails_when_jwks_request_errors(self):
jwks_response = MagicMock()
jwks_response.raise_for_status.side_effect = RuntimeError("boom")
responses = [_mock_response(DISCOVERY_DOCUMENT), jwks_response]
result, _ = _run_check(responses)
assert result["success"] is False
assert "Connection failed" in result["message"]
+10
View File
@@ -29,6 +29,16 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pytest
@pytest.fixture(autouse=True)
def _clear_torrent_fetch_cache():
"""Keep the shared torrent fetch cache from leaking between tests."""
from shelfmark.download.clients.torrent_utils import clear_torrent_fetch_cache
clear_torrent_fetch_cache()
yield
clear_torrent_fetch_cache()
@pytest.fixture
def sample_prowlarr_result():
"""Sample Prowlarr API search result."""
+1
View File
@@ -1267,6 +1267,7 @@ class TestAdminSearchPreferences:
assert data["keys"] == [
"SEARCH_MODE",
"SHOW_COMBINED_SELECTOR",
"FORCE_COMBINED_SEARCH",
"METADATA_PROVIDER",
"METADATA_PROVIDER_AUDIOBOOK",
"METADATA_PROVIDER_COMBINED",
+69
View File
@@ -597,3 +597,72 @@ def test_resolve_user_routes_expands_multiselect_event_rows(monkeypatch):
{"event": "request_fulfilled", "url": "ntfys://ntfy.sh/user-main"},
{"event": "all", "url": "ntfys://ntfy.sh/user-all"},
]
class TestAppriseProxyEnv:
"""Regression tests for issue #956 — proxy settings ignored for notifications."""
def _patch_config(self, monkeypatch, values):
from shelfmark.core import config as config_module
def _fake_get(key, default="", **_kwargs):
return values.get(key, default)
monkeypatch.setattr(config_module.config, "get", _fake_get)
def test_http_proxy_mode_injects_proxy_env(self, monkeypatch):
self._patch_config(
monkeypatch,
{
"PROXY_MODE": "http",
"HTTP_PROXY": "http://proxy.example.com:8080",
"HTTPS_PROXY": "",
"NO_PROXY": "",
},
)
monkeypatch.delenv("HTTP_PROXY", raising=False)
monkeypatch.delenv("HTTPS_PROXY", raising=False)
result = notifications_module._apprise_proxy_env()
assert result["HTTP_PROXY"] == "http://proxy.example.com:8080"
assert result["HTTPS_PROXY"] == "http://proxy.example.com:8080"
def test_socks5_proxy_mode_injects_socks_env(self, monkeypatch):
self._patch_config(
monkeypatch,
{
"PROXY_MODE": "socks5",
"SOCKS5_PROXY": "socks5://proxy.example.com:1080",
"NO_PROXY": "",
},
)
monkeypatch.delenv("HTTP_PROXY", raising=False)
monkeypatch.delenv("HTTPS_PROXY", raising=False)
result = notifications_module._apprise_proxy_env()
assert result["HTTP_PROXY"] == "socks5://proxy.example.com:1080"
assert result["HTTPS_PROXY"] == "socks5://proxy.example.com:1080"
def test_no_proxy_mode_returns_empty_dict(self, monkeypatch):
self._patch_config(monkeypatch, {"PROXY_MODE": ""})
result = notifications_module._apprise_proxy_env()
assert result == {}
def test_does_not_override_already_set_env_vars(self, monkeypatch):
self._patch_config(
monkeypatch,
{
"PROXY_MODE": "http",
"HTTP_PROXY": "http://new-proxy.example.com:8080",
"NO_PROXY": "",
},
)
monkeypatch.setenv("HTTP_PROXY", "http://existing-proxy.example.com:3128")
result = notifications_module._apprise_proxy_env()
assert "HTTP_PROXY" not in result
+37
View File
@@ -413,6 +413,43 @@ class TestOIDCCallbackEndpoint:
assert error is not None
assert "issuer validation failed" in error
@patch("shelfmark.core.oidc_routes._get_oidc_client")
def test_callback_redirects_with_signing_key_guidance_on_empty_jwks(
self, mock_get_client, client
):
fake_client = Mock()
fake_client.authorize_access_token.side_effect = KeyError("keys")
fake_client.fetch_jwk_set.return_value = {}
mock_get_client.return_value = (fake_client, MOCK_OIDC_CONFIG)
resp = client.get("/api/auth/oidc/callback?code=abc123&state=test-state")
error = _get_oidc_error(resp)
assert error is not None
assert "no token signing keys" in error
assert "Signing Key" in error
@patch("shelfmark.core.oidc_routes._get_oidc_client")
def test_callback_uses_generic_error_when_jwks_has_keys(self, mock_get_client, client):
fake_client = Mock()
fake_client.authorize_access_token.side_effect = KeyError("keys")
fake_client.fetch_jwk_set.return_value = {"keys": [{"kty": "RSA", "kid": "abc"}]}
mock_get_client.return_value = (fake_client, MOCK_OIDC_CONFIG)
resp = client.get("/api/auth/oidc/callback?code=abc123&state=test-state")
error = _get_oidc_error(resp)
assert error == "Authentication failed"
@patch("shelfmark.core.oidc_routes._get_oidc_client")
def test_callback_uses_generic_error_when_jwks_diagnosis_fails(self, mock_get_client, client):
fake_client = Mock()
fake_client.authorize_access_token.side_effect = KeyError("keys")
fake_client.fetch_jwk_set.side_effect = RuntimeError("jwks fetch failed")
mock_get_client.return_value = (fake_client, MOCK_OIDC_CONFIG)
resp = client.get("/api/auth/oidc/callback?code=abc123&state=test-state")
error = _get_oidc_error(resp)
assert error == "Authentication failed"
@patch("shelfmark.core.oidc_routes._get_oidc_client")
def test_callback_redirects_when_auto_provision_disabled_and_no_email_match(
self, mock_get_client, client
+23 -3
View File
@@ -43,10 +43,10 @@ class TestNaturalSortKey:
"file10.mp3",
]
def test_uses_filename_only(self):
def test_uses_full_path(self):
files = [Path("/z/dir/file1.mp3"), Path("/a/dir/file2.mp3")]
sorted_files = sorted(files, key=natural_sort_key)
assert sorted_files[0].name == "file1.mp3"
assert sorted_files == [Path("/a/dir/file2.mp3"), Path("/z/dir/file1.mp3")]
class TestAssignPartNumbers:
@@ -72,6 +72,23 @@ class TestAssignPartNumbers:
(Path("Chapter 10.mp3"), "03"),
]
def test_nested_folders_are_numbered_in_folder_order(self):
files = [
Path("06_Side 6/002.mp3"),
Path("01_Side 1/001.mp3"),
Path("00_Introduction/001_About.mp3"),
Path("06_Side 6/001.mp3"),
Path("01_Side 1/002.mp3"),
]
assert assign_part_numbers(files) == [
(Path("00_Introduction/001_About.mp3"), "01"),
(Path("01_Side 1/001.mp3"), "02"),
(Path("01_Side 1/002.mp3"), "03"),
(Path("06_Side 6/001.mp3"), "04"),
(Path("06_Side 6/002.mp3"), "05"),
]
def test_custom_zero_padding(self):
files = [Path("a.mp3"), Path("b.mp3")]
assert assign_part_numbers(files, zero_pad_width=3) == [
@@ -190,7 +207,10 @@ class TestEdgeCases:
def test_identical_filenames_different_dirs(self):
files = [Path("/dir2/track.mp3"), Path("/dir1/track.mp3")]
result = assign_part_numbers(files)
assert len(result) == 2
assert result == [
(Path("/dir1/track.mp3"), "01"),
(Path("/dir2/track.mp3"), "02"),
]
def test_unicode_filenames(self):
files = [Path("日本語タイトル 02.mp3"), Path("日本語タイトル 01.mp3")]
+25
View File
@@ -5,6 +5,31 @@ import types
import xmlrpc.client as stdlib_xmlrpc_client
from shelfmark.core import utils
from shelfmark.core.utils import normalize_http_url
class TestNormalizeHttpUrlQueryStripping:
"""Regression tests for issue #999 — mirror URLs with query params/fragments."""
def test_strips_query_string_from_configured_url(self) -> None:
result = normalize_http_url("http://mirror.example.com/search?token=abc123")
assert result == "http://mirror.example.com/search"
def test_strips_fragment_from_configured_url(self) -> None:
result = normalize_http_url("http://mirror.example.com/search#section")
assert result == "http://mirror.example.com/search"
def test_strips_both_query_and_fragment(self) -> None:
result = normalize_http_url("https://mirror.example.com/path?key=val&x=1#top")
assert result == "https://mirror.example.com/path"
def test_plain_url_unchanged(self) -> None:
result = normalize_http_url("http://mirror.example.com/search")
assert result == "http://mirror.example.com/search"
def test_trailing_slash_still_stripped_after_query_removal(self) -> None:
result = normalize_http_url("http://mirror.example.com/?token=x")
assert result == "http://mirror.example.com"
def test_get_hardened_xmlrpc_client_tolerates_patch_runtime_error(monkeypatch) -> None:
@@ -182,3 +182,170 @@ class TestDirectDownloadSearchQueries:
("mistborn custom query", ["en"], ["epub"]),
("mistborn custom query", None, ["epub"]),
]
# --- Distant-path language detection tests ---
def _patch_path_language(monkeypatch, enabled: bool = True):
import shelfmark.release_sources.direct_download as dd
original_get = dd.config.get
def _fake_get(key: str, default=None, user_id=None):
del user_id
if key == "DIRECT_DOWNLOAD_LANGUAGE_FROM_PATH":
return enabled
return original_get(key, default)
monkeypatch.setattr(dd.config, "get", _fake_get)
return dd
def _row_from_html(html: str):
from bs4 import BeautifulSoup
return BeautifulSoup(html, "html.parser").find("tr")
def _make_row(distant_path: str, language: str = "", record_id: str = "rec-1") -> str:
return rf"""
<tr>
<td><a href="/md5/{record_id}"><img src="cover.jpg"></a></td>
<td><span>A Book Title</span></td>
<td><span>Author Name</span></td>
<td><span>Publisher</span></td>
<td><span>2024</span></td>
<td><span>-</span></td>
<td><span>-</span></td>
<td><span>{language}</span></td>
<td><span>fiction</span></td>
<td><span>epub</span></td>
<td><span>1 mb</span></td>
<td><span>{distant_path}</span></td>
</tr>
"""
def test_detects_bracketed_language_from_distant_path(monkeypatch):
dd = _patch_path_language(monkeypatch)
row = _row_from_html(_make_row(r"lgli/N:\comics1\emule\2021.08.01\[BD FR] Scrameustache.cbz"))
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language == "fr"
assert record.download_path is not None
def test_detects_mixed_case_bracketed_language(monkeypatch):
dd = _patch_path_language(monkeypatch)
row = _row_from_html(_make_row(r"lgli/V:\comics\_0DAY3\[Fr]\BDs [Fr]\!Pdf\S\Book.pdf"))
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language == "fr"
def test_overrides_unknown_language_with_path_detection(monkeypatch):
dd = _patch_path_language(monkeypatch)
row = _row_from_html(_make_row(r"lgli/V:\comics\_0DAY3\[Fr]\Book.pdf", language="unknown"))
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language == "fr"
def test_sets_unknown_when_path_has_no_language(monkeypatch):
dd = _patch_path_language(monkeypatch)
row = _row_from_html(_make_row(r"lgli/N:\comics1\emule\NoLanguageHere.epub"))
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language == "unknown"
def test_avoids_en_false_positive_when_french_present(monkeypatch):
dd = _patch_path_language(monkeypatch)
row = _row_from_html(
_make_row(r"lgli/V:\comics\_0DAY2\Stripboeken Frans - BD en Français\[BD Fr] Book.cbr")
)
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language == "fr"
def test_keeps_row_with_missing_language_when_toggle_disabled(monkeypatch):
dd = _patch_path_language(monkeypatch, enabled=False)
row = _row_from_html(_make_row(r"lgli/N:\comics1\[BD FR] Scrameustache.cbz"))
record = dd._parse_search_result_row(row)
assert record is not None
assert record.language is None
def test_keeps_sparse_lgli_row(monkeypatch):
"""lgli rows missing author/publisher/year must not be dropped."""
dd = _patch_path_language(monkeypatch)
html = r"""
<tr>
<td><a href="/md5/sparse-1"><img src="cover.jpg"></a></td>
<td><span>Gos - 1978 - Le scrameustache T06.cbz</span></td>
<td></td><td></td><td></td><td></td><td></td><td></td>
<td><span>Comic book</span></td>
<td><span>cbz</span></td>
<td><span>17.4MB</span></td>
<td><span>lgli/N:\comics1\ftp\[BD.FR] French Comics\Book.cbz</span></td>
</tr>
"""
record = dd._parse_search_result_row(_row_from_html(html))
assert record is not None
assert record.id == "sparse-1"
assert record.language == "fr"
assert record.author is None
def test_search_books_filters_locally_when_path_language_enabled(monkeypatch):
dd = _patch_path_language(monkeypatch)
monkeypatch.setattr(dd.network, "get_aa_base_url", lambda: "https://mirror.example")
monkeypatch.setattr(dd.network, "AAMirrorSelector", lambda: object())
captured_url: dict[str, str] = {}
def _fake_html_get_page(url: str, selector, allow_bypasser_fallback=False):
del selector, allow_bypasser_fallback
captured_url["url"] = url
return r"""
<table>
<tr>
<td><a href="/md5/rec-fr"><img src="c.jpg"></a></td>
<td><span>Livre FR</span></td><td><span>Auteur</span></td>
<td><span>Editeur</span></td><td><span>2025</span></td>
<td><span>-</span></td><td><span>-</span></td><td></td>
<td><span>fiction</span></td><td><span>pdf</span></td>
<td><span>2 mb</span></td>
<td><span>lgli/V:\comics\_0DAY3\[Fr]\Book FR.pdf</span></td>
</tr>
<tr>
<td><a href="/md5/rec-en"><img src="c.jpg"></a></td>
<td><span>Book EN</span></td><td><span>Author</span></td>
<td><span>Publisher</span></td><td><span>2025</span></td>
<td><span>-</span></td><td><span>-</span></td><td></td>
<td><span>fiction</span></td><td><span>pdf</span></td>
<td><span>2 mb</span></td>
<td><span>lgli/V:\comics\_0DAY3\[En]\Book EN.pdf</span></td>
</tr>
</table>
"""
monkeypatch.setattr(dd.downloader, "html_get_page", _fake_html_get_page)
records = dd.search_books("demo", SearchFilters(lang=["fr"], format=["pdf"]))
assert "&lang=" not in captured_url["url"]
assert len(records) == 1
assert records[0].id == "rec-fr"
assert records[0].language == "fr"
def test_book_matches_requested_languages_logic():
import shelfmark.release_sources.direct_download as dd
assert dd._book_matches_requested_languages(None, {"fr"}) is True
assert dd._book_matches_requested_languages(None, set()) is True
assert dd._book_matches_requested_languages("en", {"fr"}) is False
assert dd._book_matches_requested_languages("fr", {"fr"}) is True
+79
View File
@@ -0,0 +1,79 @@
"""DoH resolver integration against the e2e platform's mock DoH responder.
The config-cluster analysis flagged DNS/DoH as a recurring break surface (#1028,
#108). A fully hermetic DoH-over-the-network profile isn't feasible in the HTTP
docker platform (DoH provider URLs are HTTPS + IP-pinned), so we exercise the
*real* ``DoHResolver`` client against the platform's mock ``doh`` role here, over
plain HTTP on localhost. This runs in normal CI (not just the nightly docker
matrix) and guards the DoH JSON-parsing path the app relies on.
"""
from __future__ import annotations
import importlib.util
import os
import threading
from pathlib import Path
from wsgiref.simple_server import WSGIServer, make_server
import pytest
MOCK_PATH = Path(__file__).resolve().parents[1] / "e2e" / "platform" / "mocks" / "mock_services.py"
def _load_mock_doh_app(doh_map: str):
"""Import the platform mock_services module wired for the ``doh`` role.
The module wires its routes at import time from ``MOCK_ROLE``/``DOH_MAP``, so
those must be set before loading it.
"""
os.environ["MOCK_ROLE"] = "doh"
os.environ["DOH_MAP"] = doh_map
spec = importlib.util.spec_from_file_location("mock_doh_services", MOCK_PATH)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module.app
@pytest.fixture(scope="module")
def doh_url():
if not MOCK_PATH.exists():
pytest.skip(f"platform mock not found at {MOCK_PATH}")
app = _load_mock_doh_app("aa.mock.test=172.30.0.10,cf.mock.test=172.30.0.11")
server: WSGIServer = make_server("127.0.0.1", 0, app)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
# Google JSON DoH style uses the /resolve endpoint.
yield f"http://127.0.0.1:{server.server_port}/resolve"
finally:
server.shutdown()
def _resolver(doh_url: str):
from shelfmark.download.network import DoHResolver
# hostname/ip args are the DoH server's own identity (used only for recursion
# avoidance); the localhost values here are irrelevant to the lookups under test.
return DoHResolver(doh_url, "127.0.0.1", "127.0.0.1")
def test_doh_resolves_mapped_host(doh_url) -> None:
"""The real DoH client parses the mock's JSON answer into an A record."""
assert _resolver(doh_url).resolve("aa.mock.test", "A") == ["172.30.0.10"]
def test_doh_nxdomain_returns_empty_not_error(doh_url) -> None:
"""An unmapped name yields an empty list (Status 3), not an exception —
the path that, when mishandled, surfaced as silent download failures."""
assert _resolver(doh_url).resolve("unmapped.invalid", "A") == []
def test_doh_resolver_caches_within_ttl(doh_url) -> None:
"""A second lookup is served from cache (the resolver's documented behaviour)."""
resolver = _resolver(doh_url)
first = resolver.resolve("cf.mock.test", "A")
assert first == ["172.30.0.11"]
assert ("cf.mock.test", "A") in resolver._cache
assert resolver.resolve("cf.mock.test", "A") == first
+132
View File
@@ -137,3 +137,135 @@ def test_system_failover_getaddrinfo_retries_after_dns_switch(monkeypatch):
assert result == [
(network.socket.AF_INET, network.socket.SOCK_STREAM, 6, "", ("203.0.113.10", 443))
]
def _addrinfo(ip):
return [(2, 1, 6, "", (ip, 443))]
class _FakeDoHResolver:
def __init__(self, ips):
self._ips = ips
def resolve(self, _hostname, _record_type):
return list(self._ips)
def test_build_detection_doh_resolver_uses_selected_provider(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(
network,
"DNS_PROVIDERS",
[
("cloudflare", ["1.1.1.1", "1.0.0.1"], "https://cloudflare-dns.com/dns-query"),
("quad9", ["9.9.9.9", "149.112.112.112"], "https://dns.quad9.net/dns-query"),
],
)
monkeypatch.setattr(network, "_current_dns_index", 1) # user selected quad9
resolver = network._build_detection_doh_resolver()
assert resolver is not None
assert resolver.base_url == "https://dns.quad9.net/dns-query"
assert resolver.hostname == "dns.quad9.net"
assert resolver.ip == "9.9.9.9"
def test_build_detection_doh_resolver_falls_back_to_first_provider(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(
network,
"DNS_PROVIDERS",
[
("cloudflare", ["1.1.1.1", "1.0.0.1"], "https://cloudflare-dns.com/dns-query"),
("quad9", ["9.9.9.9"], "https://dns.quad9.net/dns-query"),
],
)
monkeypatch.setattr(network, "_current_dns_index", -1) # system / not yet rotated
resolver = network._build_detection_doh_resolver()
assert resolver is not None
assert resolver.base_url == "https://cloudflare-dns.com/dns-query"
assert resolver.ip == "1.1.1.1"
def test_detect_dns_interference_flags_divergent_resolvers(monkeypatch):
import shelfmark.download.network as network
# System DNS (hijacked) returns an ISP block-page IP; DoH returns the real one.
monkeypatch.setattr(network, "original_getaddrinfo", lambda *a, **k: _addrinfo("198.51.100.1"))
monkeypatch.setattr(
network, "_build_detection_doh_resolver", lambda: _FakeDoHResolver(["203.0.113.7"])
)
result = network.detect_dns_interference("annas-archive.pk")
assert result == {"system_ips": ["198.51.100.1"], "doh_ips": ["203.0.113.7"]}
def test_detect_dns_interference_none_when_resolvers_agree(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(network, "original_getaddrinfo", lambda *a, **k: _addrinfo("203.0.113.7"))
monkeypatch.setattr(
network, "_build_detection_doh_resolver", lambda: _FakeDoHResolver(["203.0.113.7"])
)
assert network.detect_dns_interference("annas-archive.pk") is None
def test_detect_dns_interference_none_when_doh_unavailable(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(network, "original_getaddrinfo", lambda *a, **k: _addrinfo("198.51.100.1"))
monkeypatch.setattr(network, "_build_detection_doh_resolver", lambda: None)
assert network.detect_dns_interference("annas-archive.pk") is None
def test_detect_dns_interference_skips_ip_and_local(monkeypatch):
import shelfmark.download.network as network
def _should_not_run():
raise AssertionError("resolver should not be built for IP/local hosts")
monkeypatch.setattr(network, "_build_detection_doh_resolver", _should_not_run)
assert network.detect_dns_interference("1.2.3.4") is None
assert network.detect_dns_interference("localhost") is None
def test_note_possible_dns_interference_warns_once_and_sets_flag(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(network, "_dns_interference_warned", set())
monkeypatch.setattr(network, "_dns_interference_active", False)
calls: list[str] = []
monkeypatch.setattr(
network,
"detect_dns_interference",
lambda host: (
calls.append(host) or {"system_ips": ["198.51.100.1"], "doh_ips": ["203.0.113.7"]}
),
)
assert network.note_possible_dns_interference("annas-archive.pk") is True
assert network.dns_interference_detected() is True
# A repeat check for the same host must not re-run the costly detection.
assert network.note_possible_dns_interference("annas-archive.pk") is True
assert calls == ["annas-archive.pk"]
def test_note_possible_dns_interference_no_detection_keeps_flag_false(monkeypatch):
import shelfmark.download.network as network
monkeypatch.setattr(network, "_dns_interference_warned", set())
monkeypatch.setattr(network, "_dns_interference_active", False)
monkeypatch.setattr(network, "detect_dns_interference", lambda _host: None)
assert network.note_possible_dns_interference("annas-archive.pk") is False
assert network.dns_interference_detected() is False

Some files were not shown because too many files have changed in this diff Show More