Commit Graph

2921 Commits

Author SHA1 Message Date
Thomas Eizinger
8539f2ff2c refactor(gateway): update flow-logs fields in subject (#10939)
Resolves: #10928
2025-11-24 15:46:43 +00:00
Thomas Eizinger
0c5ca66f57 fix(connlib): override query ID of DoH response (#10931)
As per the RFC, queries to DoH servers should always set their query ID
to 0. This is more cache-friendly because two queries for the same
domain end up being byte-for-byte equivalent in the HTTP request. When
transported over HTTP, the query ID is obsolete because the response can
be unambiguously mapped back to the request already.

Connlib's DoH feature zeros out the query ID in the IO layer. To
correctly test this functionality, we therefore extend the test-suite to
do the same and restore the original query ID before sending back the
response on the original transport.

This fixes a bug where all DNS queries that were forwarded to a DoH
server incorrectly had their query ID set to 0.
2025-11-24 07:45:53 +00:00
Thomas Eizinger
aab779e68b fix(connlib): signal all local candidates on upsert (#10920)
Firezone's UDP connections are designed to be idempotent. If a Client
discards its "half" of the connection but the Gateway still keeps the
state around, a subsequent connection setup by the Client will reuse
connection state on the Gateway. To fully support this, `snownet`
re-sends all its local candidates to the remote peer whenever a
connection gets upserted.

The current `seed_agent_with_local_candidates` function attempts to do
this job but its design overlooked a crucial detail: Re-adding a
candidate that the `IceAgent` already knows about is considered to be
redundant. As such, the candidate is not re-signalled to the remote!

The real-world consequences for this are subtle. `str0m`'s support for
peer-reflexive candidate means that incoming STUN binding requests are
still answered, even if they come from an address that the agent doesn't
know anything about, i.e. it has never been told about that candidate.
Thus, what happens right now is that when a Client re-creates a
connection that is still present on the Gateway, it will start receiving
STUN binding requests for candidates it doesn't know about and create
peer-reflexive candidates for them.

Where this does show up is in our test-suite which has fairly strict
timing constraints. When we simulate the re-deploy of relays, we expect
connections to be migrated to a new relay immediately. To support this,
the current relay candidates are invalidated on both sides. This however
only works if the current candidate is correctly recognised by the local
ICE agent. Peer-reflexive candidates are created on-demand and typically
only serve a placeholder-like role until we learn about the real
candidate that is being used. Due to the above described behaviour of
`seed_agent_with_local_candidates`, this however may not happen at all.
As a result, attempting to invalidate a relay candidate fails because we
don't recognise the relay candidate as we only have a peer-reflexive
one.

Putting all of this together, whilst not re-sending all candidates
doesn't cause immediate issues for a connection, it may cause problems
at a later point when we are trying to invalidate a currently active
candidate to achieve a speedy failover to a new one.
2025-11-21 04:01:42 +00:00
Thomas Eizinger
62a39a81d0 fix(connlib): index tunnelled DNS queries by source socket (#10914)
It appears that several systems (at least MacOS) may send DNS queries to
the same server with the same query ID but from different source
sockets. Within connlib, we operate multiple DNS servers (one for each
upstream) and use the tuple of server address and query ID to remember
the necessary state we need to map the response back once we have the
response from the upstream server.

Given the discovery that this tuple is not necessarily unique, we now
need to also track the source socket that _we_ are using to send our
queries in order to correctly remember, which socket we need to send the
response back to. For that, we extend the layer 3 UDP and TCP clients to
return us the socket they are using for each query that we queue.

In very specific circumstances, this can still fail. In particular, when
connlib receives an SRV or TXT query for a resource, it resolves that
query in the context of the resource's site by sending it to port 53535
of the Gateway's TUN device. The Gateway listens to DNS queries on this
port and resolves them using its configured system resolvers. It however
only listens on a single address, meaning we may be forwarding queries
from several of connlib's "servers" to a single query which again may
break the uniqueness constraint if two queries with the same ID are
received at the same time because we would reuse the TCP connection to
the resolver running in the Gateway and thus send them from the same
source port.

We consider this case to be sufficiently rare and handle it by just
failing the 2nd DNS query. There may be ways of resolving it but it
requires a bigger refactoring of how we establish TCP connections to
upstream resolvers.
2025-11-20 22:39:30 +00:00
Thomas Eizinger
32df4b399a chore: modularize .tool-versions (#10919)
Not all tools are needed for all parts of the codebase. In order to avoid installing all tools, we create nested `.tool-versions` files that list the specific dev-tools needed for a certain part of the product.
2025-11-21 08:28:05 +11:00
Thomas Eizinger
ffce55376f chore(connlib): add time-related tests to l3-udp-dns-client (#10913)
This module didn't have any tests yet so I generated some with Claude
and trimmed them down to a meaningful set.
2025-11-19 07:39:49 +00:00
Thomas Eizinger
aa4a08889b test(connlib): set TCP connections as connected after roaming (#10910)
TCP connections have a keep-alive mechanism and therefore will
automatically trigger a new connection to a resource after roaming. We
need to model this in our tests by setting the resource as connected
whenever we reset the network state.
2025-11-19 06:49:47 +00:00
Thomas Eizinger
ea5e734254 test(connlib): fix off-by-1 second error in NAT table test (#10912)
A CI failure uncovered that we have an off-by-1 second error in our NAT
table test. The mapping only expires after the last packet seen + the
protocol TTL, not after the first sent one + protocol TTL.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-19 06:32:13 +00:00
Thomas Eizinger
01e16e87d6 feat(connlib): support DoH (#10876)
Building on top of a series of refactors and smaller features, this PR
enables connlib to send DNS queries over HTTPS to one or more configured
DoH providers.

A DoH server itself is addressed via a domain which first needs to be
resolved before it can be contacted. The RFC recommends to perform this
bootstrapping using the system DNS resolvers. For connlib, this is a bit
tricky because the system resolvers may already be set to connlib's
sentinel servers by the time we need to bootstrap the DoH clients.
Therefore, we maintain a dedicated UDP DNS client inside connlib's `Io`
component which is always configured with the latest system DNS
resolvers known to connlib.

The actual bootstrapping of a DoH client happens in the following cases:

1. Our TUN device configuration changes and the configured DNS servers
mapping contains DoH upstreams.
2. We need to make a DNS query to a DoH server but don't have a client
yet.

The first case ensures we bootstrap the DoH clients as early as
possible. The latter case ensures we have a self-healing behaviour in
case the TCP connection to the DoH server breaks (in which case the DoH
client will be de-allocated).

Once the DoH client is initialized, making queries with it is a trivial
act of sending an HTTP request and parsing the HTTP response. Within
connlib, this now requires almost no special handling apart from a new
`dns::Upstream` type that differentiates between Do53 servers (addressed
by a `SocketAddr`) and DoH servers (addressed by a `Url`).

Related: #10764
Related: #10788
Related: #10850
Related: #10851
Related: #10856
Related: #10857
Related: #10871
Related: #10872
Related: #10875
Related: #10881
Resolves: #10790
2025-11-19 05:10:52 +00:00
Thomas Eizinger
9b0ae92b29 feat(gateway): extend ICE timeout (#10887)
Currently, a `snownet` Client and Server always have the same ICE
timeout configuration. This doesn't necessarily have to be the case. A
Gateway cannot establish connections to a Client anyway and thus, we can
have much laxer requirements on when we detect that a Client has
disappeared (without saying "goodbye").

Extending the idle and default ICE timeout values should hopefully
reduce the number of false-positive disconnects that users may
experience where a Gateway cuts a connection because it believes the
Client is gone when in reality, perhaps a few STUN packets just got lost
or backed up.

Changing the ICE timeout exposes a few corner-cases in how we track and
use time within `snownet`. In particular, it is now obviously possible
for a Gateway to still retain the connection state of a Client whilst
the Client has long disconnected but now reconnects using the same ICE
credentials and private key.

Our proptests uncovered some state misalignment in that scenario due to
some remaining time impurity within `boringtun` (see
https://github.com/firezone/boringtun/pull/126 for details). In
addition, our idle state transitions needed to be updated to also take
into account candidate changes on both sides in order to achieve a
deterministic outcome.
2025-11-19 03:02:13 +00:00
Thomas Eizinger
ccee476daa fix(snownet): allow direct connections on port 3478 (#10907)
When a NAT between the Client and Gateway remaps the source port to
3478, it is tricky to de-multiplex that p2p traffic from the packets we
receive from a relay. Currently, we handle this edge-case by dropping
these packets which effectively forces a fallback to a relayed
connection.

Remapping onto exactly this port is likely to be quite rare in practice
which is why this behaviour was implemented in the first place.

We can however do better than that by remembering, which relays we have
previously been connected to. That is because the problem with traffic
on port 3478 isn't so much the correct handling in case it _is_ p2p
traffic: We can simply check whether the IP is one of the relays we are
connected to. The problem is the mis-classification as p2p traffic in
case they are packets from a relay that we have disconnected from,
causing a log-spam of "unknown packet".

To gracefully handle this, we now remember up to 64 relay IPs that we
have been connected to in the past. This ensures we can correctly
classify traffic from previous relays as such and drop the packet whilst
at the same time continuing processing of packets from unknown origins
which likely then is p2p traffic.

The effect of this is that we can now establish direct connections to
peers, even if a NAT inbetween remaps their source port to 3478. To make
this fix easier, we precede it with a refactoring of introducing an
`Allocations` container for the map of `Allocations`. This allows us to
easily track, when we remove a value from the map and then remember the
relay's IPs.

This came up as part of test failures in #10887.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-19 00:12:08 +00:00
Thomas Eizinger
35b28692de feat(gateway): improve state tracking of DNS resource NAT (#10868)
Right now, the state tracking within the DNS resource NAT table is
pretty simple:

- We map from inside to outside and back
- When we see a TCP RST, we remove it immediately

To improve our logs a bit and make the NAT table more robust, we extend
it by:

- Tracking last inbound and outbound packet
- Tracking FIN and RST flags

This allows us to fully observe e.g. a TCP shutdown where both parties
send TCP FIN. It also allows us to remove entries that have never been
confirmed after a shorter amount of time.

Resolves: #10795

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-18 23:48:04 +00:00
dependabot[bot]
28f0dac50a build(deps): bump the react group in /rust/gui-client with 5 updates (#10833)
Bumps the react group in /rust/gui-client with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) |
`19.1.1` | `19.2.0` |
|
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
| `19.1.15` | `19.2.2` |
|
[react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom)
| `19.1.1` | `19.2.0` |
|
[@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom)
| `19.1.9` | `19.2.1` |
|
[react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router)
| `7.9.3` | `7.9.4` |

Updates `react` from 19.1.1 to 19.2.0
<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.0 (Oct 1, 2025)</h2>
<p>Below is a list of all new features, APIs, and bug fixes.</p>
<p>Read the <a href="https://react.dev/blog/2025/10/01/react-19-2">React
19.2 release post</a> for more information.</p>
<h2>New React Features</h2>
<ul>
<li><a
href="https://react.dev/reference/react/Activity"><code>&lt;Activity&gt;</code></a>:
A new API to hide and restore the UI and internal state of its
children.</li>
<li><a
href="https://react.dev/reference/react/useEffectEvent"><code>useEffectEvent</code></a>
is a React Hook that lets you extract non-reactive logic into an <a
href="https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event">Effect
Event</a>.</li>
<li><a
href="https://react.dev/reference/react/cacheSignal"><code>cacheSignal</code></a>
(for RSCs) lets your know when the <code>cache()</code> lifetime is
over.</li>
<li><a
href="https://react.dev/reference/developer-tooling/react-performance-tracks">React
Performance tracks</a> appear on the Performance panel’s timeline in
your browser developer tools</li>
</ul>
<h2>New React DOM Features</h2>
<ul>
<li>Added resume APIs for partial pre-rendering with Web Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resume"><code>resume</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerender"><code>resumeAndPrerender</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Added resume APIs for partial pre-rendering with Node Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resumeToPipeableStream"><code>resumeToPipeableStream</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerenderToNodeStream"><code>resumeAndPrerenderToNodeStream</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Updated <a
href="https://react.dev/reference/react-dom/static/prerender"><code>prerender</code></a>
APIs to return a <code>postponed</code> state that can be passed to the
<code>resume</code> APIs.</li>
</ul>
<h2>Notable changes</h2>
<ul>
<li>React DOM now batches suspense boundary reveals, matching the
behavior of client side rendering. This change is especially noticeable
when animating the reveal of Suspense boundaries e.g. with the upcoming
<code>&lt;ViewTransition&gt;</code> Component. React will batch as much
reveals as possible before the first paint while trying to hit popular
first-contentful paint metrics.</li>
<li>Add Node Web Streams (<code>prerender</code>,
<code>renderToReadableStream</code>) to server-side-rendering APIs for
Node.js</li>
<li>Use underscore instead of <code>:</code> IDs generated by useId</li>
</ul>
<h2>All Changes</h2>
<h3>React</h3>
<ul>
<li><code>&lt;Activity /&gt;</code> was developed over many years,
starting before <code>ClassComponent.setState</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> and
many others)</li>
<li>Stringify context as &quot;SomeContext&quot; instead of
&quot;SomeContext.Provider&quot; (<a
href="https://github.com/kassens"><code>@​kassens</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33507">#33507</a>)</li>
<li>Include stack of cause of React instrumentation errors with
<code>%o</code> placeholder (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34198">#34198</a>)</li>
<li>Fix infinite <code>useDeferredValue</code> loop in popstate event
(<a href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32821">#32821</a>)</li>
<li>Fix a bug when an initial value was passed to
<code>useDeferredValue</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34376">#34376</a>)</li>
<li>Fix a crash when submitting forms with Client Actions (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33055">#33055</a>)</li>
<li>Hide/unhide the content of dehydrated suspense boundaries if they
resuspend (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32900">#32900</a>)</li>
<li>Avoid stack overflow on wide trees during Hot Reload (<a
href="https://github.com/sophiebits"><code>@​sophiebits</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34145">#34145</a>)</li>
<li>Improve Owner and Component stacks in various places (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/33629">#33629</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33724">#33724</a>,
<a
href="https://redirect.github.com/facebook/react/pull/32735">#32735</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33723">#33723</a>)</li>
<li>Add <code>cacheSignal</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33557">#33557</a>)</li>
</ul>
<h3>React DOM</h3>
<ul>
<li>Block on Suspensey Fonts during reveal of server-side-rendered
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33342">#33342</a>)</li>
<li>Use underscore instead of <code>:</code> for IDs generated by
<code>useId</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/32001">#32001</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33342">facebook/react#33342</a><a
href="https://redirect.github.com/facebook/react/pull/33099">#33099</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33422">#33422</a>)</li>
<li>Stop warning when ARIA 1.3 attributes are used (<a
href="https://github.com/Abdul-Omira"><code>@​Abdul-Omira</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34264">#34264</a>)</li>
<li>Allow <code>nonce</code> to be used on hoistable styles (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32461">#32461</a>)</li>
<li>Warn for using a React owned node as a Container if it also has text
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32774">#32774</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/blob/main/CHANGELOG.md">react's
changelog</a>.</em></p>
<blockquote>
<h2>19.2.0 (October 1st, 2025)</h2>
<p>Below is a list of all new features, APIs, and bug fixes.</p>
<p>Read the <a href="https://react.dev/blog/2025/10/01/react-19-2">React
19.2 release post</a> for more information.</p>
<h3>New React Features</h3>
<ul>
<li><a
href="https://react.dev/reference/react/Activity"><code>&lt;Activity&gt;</code></a>:
A new API to hide and restore the UI and internal state of its
children.</li>
<li><a
href="https://react.dev/reference/react/useEffectEvent"><code>useEffectEvent</code></a>
is a React Hook that lets you extract non-reactive logic into an <a
href="https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event">Effect
Event</a>.</li>
<li><a
href="https://react.dev/reference/react/cacheSignal"><code>cacheSignal</code></a>
(for RSCs) lets your know when the <code>cache()</code> lifetime is
over.</li>
<li><a
href="https://react.dev/reference/dev-tools/react-performance-tracks">React
Performance tracks</a> appear on the Performance panel’s timeline in
your browser developer tools</li>
</ul>
<h3>New React DOM Features</h3>
<ul>
<li>Added resume APIs for partial pre-rendering with Web Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resume"><code>resume</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerender"><code>resumeAndPrerender</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Added resume APIs for partial pre-rendering with Node Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resumeToPipeableStream"><code>resumeToPipeableStream</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerenderToNodeStream"><code>resumeAndPrerenderToNodeStream</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Updated <a
href="https://react.dev/reference/react-dom/static/prerender"><code>prerender</code></a>
APIs to return a <code>postponed</code> state that can be passed to the
<code>resume</code> APIs.</li>
</ul>
<h3>Notable changes</h3>
<ul>
<li>React DOM now batches suspense boundary reveals, matching the
behavior of client side rendering. This change is especially noticeable
when animating the reveal of Suspense boundaries e.g. with the upcoming
<code>&lt;ViewTransition&gt;</code> Component. React will batch as much
reveals as possible before the first paint while trying to hit popular
first-contentful paint metrics.</li>
<li>Add Node Web Streams (<code>prerender</code>,
<code>renderToReadableStream</code>) to server-side-rendering APIs for
Node.js</li>
<li>Use underscore instead of <code>:</code> IDs generated by useId</li>
</ul>
<h3>All Changes</h3>
<h4>React</h4>
<ul>
<li><code>&lt;Activity /&gt;</code> was developed over many years,
starting before <code>ClassComponent.setState</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> and
many others)</li>
<li>Stringify context as &quot;SomeContext&quot; instead of
&quot;SomeContext.Provider&quot; (<a
href="https://github.com/kassens"><code>@​kassens</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33507">#33507</a>)</li>
<li>Include stack of cause of React instrumentation errors with
<code>%o</code> placeholder (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34198">#34198</a>)</li>
<li>Fix infinite <code>useDeferredValue</code> loop in popstate event
(<a href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32821">#32821</a>)</li>
<li>Fix a bug when an initial value was passed to
<code>useDeferredValue</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34376">#34376</a>)</li>
<li>Fix a crash when submitting forms with Client Actions (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33055">#33055</a>)</li>
<li>Hide/unhide the content of dehydrated suspense boundaries if they
resuspend (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32900">#32900</a>)</li>
<li>Avoid stack overflow on wide trees during Hot Reload (<a
href="https://github.com/sophiebits"><code>@​sophiebits</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34145">#34145</a>)</li>
<li>Improve Owner and Component stacks in various places (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/33629">#33629</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33724">#33724</a>,
<a
href="https://redirect.github.com/facebook/react/pull/32735">#32735</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33723">#33723</a>)</li>
<li>Add <code>cacheSignal</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33557">#33557</a>)</li>
</ul>
<h4>React DOM</h4>
<ul>
<li>Block on Suspensey Fonts during reveal of server-side-rendered
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33342">#33342</a>)</li>
<li>Use underscore instead of <code>:</code> for IDs generated by
<code>useId</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/32001">#32001</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33342">facebook/react#33342</a><a
href="https://redirect.github.com/facebook/react/pull/33099">#33099</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33422">#33422</a>)</li>
<li>Stop warning when ARIA 1.3 attributes are used (<a
href="https://github.com/Abdul-Omira"><code>@​Abdul-Omira</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34264">#34264</a>)</li>
<li>Allow <code>nonce</code> to be used on hoistable styles (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32461">#32461</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5667a41fe4"><code>5667a41</code></a>
Bump next prerelease version numbers (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34639">#34639</a>)</li>
<li><a
href="8bb7241f4c"><code>8bb7241</code></a>
Bump useEffectEvent to Canary (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34610">#34610</a>)</li>
<li><a
href="e3c9656d20"><code>e3c9656</code></a>
Ensure Performance Track are Clamped and Don't overlap (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34509">#34509</a>)</li>
<li><a
href="68f00c901c"><code>68f00c9</code></a>
Release Activity in Canary (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34374">#34374</a>)</li>
<li><a
href="0e10ee906e"><code>0e10ee9</code></a>
[Reconciler] Set ProfileMode for Host Root Fiber by default in dev (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34432">#34432</a>)</li>
<li><a
href="3bf8ab430e"><code>3bf8ab4</code></a>
Add missing Activity export to development mode (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34439">#34439</a>)</li>
<li><a
href="1549bda33f"><code>1549bda</code></a>
[Flight] Only assign <code>_store</code> in dev mode when creating lazy
types (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34354">#34354</a>)</li>
<li><a
href="bb6f0c8d2f"><code>bb6f0c8</code></a>
[Flight] Fix wrong missing key warning when static child is blocked (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34350">#34350</a>)</li>
<li><a
href="05addfc663"><code>05addfc</code></a>
Update Flow to 0.266 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34271">#34271</a>)</li>
<li><a
href="ec5dd0ab3a"><code>ec5dd0a</code></a>
Update Flow to 0.257 (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react/issues/34253">#34253</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/facebook/react/commits/v19.2.0/packages/react">compare
view</a></li>
</ul>
</details>
<br />

Updates `@types/react` from 19.1.15 to 19.2.2
<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.1.1 to 19.2.0
<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.0 (Oct 1, 2025)</h2>
<p>Below is a list of all new features, APIs, and bug fixes.</p>
<p>Read the <a href="https://react.dev/blog/2025/10/01/react-19-2">React
19.2 release post</a> for more information.</p>
<h2>New React Features</h2>
<ul>
<li><a
href="https://react.dev/reference/react/Activity"><code>&lt;Activity&gt;</code></a>:
A new API to hide and restore the UI and internal state of its
children.</li>
<li><a
href="https://react.dev/reference/react/useEffectEvent"><code>useEffectEvent</code></a>
is a React Hook that lets you extract non-reactive logic into an <a
href="https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event">Effect
Event</a>.</li>
<li><a
href="https://react.dev/reference/react/cacheSignal"><code>cacheSignal</code></a>
(for RSCs) lets your know when the <code>cache()</code> lifetime is
over.</li>
<li><a
href="https://react.dev/reference/developer-tooling/react-performance-tracks">React
Performance tracks</a> appear on the Performance panel’s timeline in
your browser developer tools</li>
</ul>
<h2>New React DOM Features</h2>
<ul>
<li>Added resume APIs for partial pre-rendering with Web Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resume"><code>resume</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerender"><code>resumeAndPrerender</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Added resume APIs for partial pre-rendering with Node Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resumeToPipeableStream"><code>resumeToPipeableStream</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerenderToNodeStream"><code>resumeAndPrerenderToNodeStream</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Updated <a
href="https://react.dev/reference/react-dom/static/prerender"><code>prerender</code></a>
APIs to return a <code>postponed</code> state that can be passed to the
<code>resume</code> APIs.</li>
</ul>
<h2>Notable changes</h2>
<ul>
<li>React DOM now batches suspense boundary reveals, matching the
behavior of client side rendering. This change is especially noticeable
when animating the reveal of Suspense boundaries e.g. with the upcoming
<code>&lt;ViewTransition&gt;</code> Component. React will batch as much
reveals as possible before the first paint while trying to hit popular
first-contentful paint metrics.</li>
<li>Add Node Web Streams (<code>prerender</code>,
<code>renderToReadableStream</code>) to server-side-rendering APIs for
Node.js</li>
<li>Use underscore instead of <code>:</code> IDs generated by useId</li>
</ul>
<h2>All Changes</h2>
<h3>React</h3>
<ul>
<li><code>&lt;Activity /&gt;</code> was developed over many years,
starting before <code>ClassComponent.setState</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> and
many others)</li>
<li>Stringify context as &quot;SomeContext&quot; instead of
&quot;SomeContext.Provider&quot; (<a
href="https://github.com/kassens"><code>@​kassens</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33507">#33507</a>)</li>
<li>Include stack of cause of React instrumentation errors with
<code>%o</code> placeholder (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34198">#34198</a>)</li>
<li>Fix infinite <code>useDeferredValue</code> loop in popstate event
(<a href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32821">#32821</a>)</li>
<li>Fix a bug when an initial value was passed to
<code>useDeferredValue</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34376">#34376</a>)</li>
<li>Fix a crash when submitting forms with Client Actions (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33055">#33055</a>)</li>
<li>Hide/unhide the content of dehydrated suspense boundaries if they
resuspend (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32900">#32900</a>)</li>
<li>Avoid stack overflow on wide trees during Hot Reload (<a
href="https://github.com/sophiebits"><code>@​sophiebits</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34145">#34145</a>)</li>
<li>Improve Owner and Component stacks in various places (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/33629">#33629</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33724">#33724</a>,
<a
href="https://redirect.github.com/facebook/react/pull/32735">#32735</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33723">#33723</a>)</li>
<li>Add <code>cacheSignal</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33557">#33557</a>)</li>
</ul>
<h3>React DOM</h3>
<ul>
<li>Block on Suspensey Fonts during reveal of server-side-rendered
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33342">#33342</a>)</li>
<li>Use underscore instead of <code>:</code> for IDs generated by
<code>useId</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/32001">#32001</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33342">facebook/react#33342</a><a
href="https://redirect.github.com/facebook/react/pull/33099">#33099</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33422">#33422</a>)</li>
<li>Stop warning when ARIA 1.3 attributes are used (<a
href="https://github.com/Abdul-Omira"><code>@​Abdul-Omira</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34264">#34264</a>)</li>
<li>Allow <code>nonce</code> to be used on hoistable styles (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32461">#32461</a>)</li>
<li>Warn for using a React owned node as a Container if it also has text
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32774">#32774</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/facebook/react/blob/main/CHANGELOG.md">react-dom's
changelog</a>.</em></p>
<blockquote>
<h2>19.2.0 (October 1st, 2025)</h2>
<p>Below is a list of all new features, APIs, and bug fixes.</p>
<p>Read the <a href="https://react.dev/blog/2025/10/01/react-19-2">React
19.2 release post</a> for more information.</p>
<h3>New React Features</h3>
<ul>
<li><a
href="https://react.dev/reference/react/Activity"><code>&lt;Activity&gt;</code></a>:
A new API to hide and restore the UI and internal state of its
children.</li>
<li><a
href="https://react.dev/reference/react/useEffectEvent"><code>useEffectEvent</code></a>
is a React Hook that lets you extract non-reactive logic into an <a
href="https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event">Effect
Event</a>.</li>
<li><a
href="https://react.dev/reference/react/cacheSignal"><code>cacheSignal</code></a>
(for RSCs) lets your know when the <code>cache()</code> lifetime is
over.</li>
<li><a
href="https://react.dev/reference/dev-tools/react-performance-tracks">React
Performance tracks</a> appear on the Performance panel’s timeline in
your browser developer tools</li>
</ul>
<h3>New React DOM Features</h3>
<ul>
<li>Added resume APIs for partial pre-rendering with Web Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resume"><code>resume</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerender"><code>resumeAndPrerender</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Added resume APIs for partial pre-rendering with Node Streams:
<ul>
<li><a
href="https://react.dev/reference/react-dom/server/resumeToPipeableStream"><code>resumeToPipeableStream</code></a>:
to resume a prerender to a stream.</li>
<li><a
href="https://react.dev/reference/react-dom/static/resumeAndPrerenderToNodeStream"><code>resumeAndPrerenderToNodeStream</code></a>:
to resume a prerender to HTML.</li>
</ul>
</li>
<li>Updated <a
href="https://react.dev/reference/react-dom/static/prerender"><code>prerender</code></a>
APIs to return a <code>postponed</code> state that can be passed to the
<code>resume</code> APIs.</li>
</ul>
<h3>Notable changes</h3>
<ul>
<li>React DOM now batches suspense boundary reveals, matching the
behavior of client side rendering. This change is especially noticeable
when animating the reveal of Suspense boundaries e.g. with the upcoming
<code>&lt;ViewTransition&gt;</code> Component. React will batch as much
reveals as possible before the first paint while trying to hit popular
first-contentful paint metrics.</li>
<li>Add Node Web Streams (<code>prerender</code>,
<code>renderToReadableStream</code>) to server-side-rendering APIs for
Node.js</li>
<li>Use underscore instead of <code>:</code> IDs generated by useId</li>
</ul>
<h3>All Changes</h3>
<h4>React</h4>
<ul>
<li><code>&lt;Activity /&gt;</code> was developed over many years,
starting before <code>ClassComponent.setState</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> and
many others)</li>
<li>Stringify context as &quot;SomeContext&quot; instead of
&quot;SomeContext.Provider&quot; (<a
href="https://github.com/kassens"><code>@​kassens</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33507">#33507</a>)</li>
<li>Include stack of cause of React instrumentation errors with
<code>%o</code> placeholder (<a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34198">#34198</a>)</li>
<li>Fix infinite <code>useDeferredValue</code> loop in popstate event
(<a href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32821">#32821</a>)</li>
<li>Fix a bug when an initial value was passed to
<code>useDeferredValue</code> (<a
href="https://github.com/acdlite"><code>@​acdlite</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34376">#34376</a>)</li>
<li>Fix a crash when submitting forms with Client Actions (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33055">#33055</a>)</li>
<li>Hide/unhide the content of dehydrated suspense boundaries if they
resuspend (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32900">#32900</a>)</li>
<li>Avoid stack overflow on wide trees during Hot Reload (<a
href="https://github.com/sophiebits"><code>@​sophiebits</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34145">#34145</a>)</li>
<li>Improve Owner and Component stacks in various places (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/33629">#33629</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33724">#33724</a>,
<a
href="https://redirect.github.com/facebook/react/pull/32735">#32735</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33723">#33723</a>)</li>
<li>Add <code>cacheSignal</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33557">#33557</a>)</li>
</ul>
<h4>React DOM</h4>
<ul>
<li>Block on Suspensey Fonts during reveal of server-side-rendered
content (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a> <a
href="https://redirect.github.com/facebook/react/pull/33342">#33342</a>)</li>
<li>Use underscore instead of <code>:</code> for IDs generated by
<code>useId</code> (<a
href="https://github.com/sebmarkbage"><code>@​sebmarkbage</code></a>, <a
href="https://github.com/eps1lon"><code>@​eps1lon</code></a>: <a
href="https://redirect.github.com/facebook/react/pull/32001">#32001</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33342">facebook/react#33342</a><a
href="https://redirect.github.com/facebook/react/pull/33099">#33099</a>,
<a
href="https://redirect.github.com/facebook/react/pull/33422">#33422</a>)</li>
<li>Stop warning when ARIA 1.3 attributes are used (<a
href="https://github.com/Abdul-Omira"><code>@​Abdul-Omira</code></a> <a
href="https://redirect.github.com/facebook/react/pull/34264">#34264</a>)</li>
<li>Allow <code>nonce</code> to be used on hoistable styles (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a> <a
href="https://redirect.github.com/facebook/react/pull/32461">#32461</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="861811347b"><code>8618113</code></a>
Bump scheduler version (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34671">#34671</a>)</li>
<li><a
href="1bd1f01f2a"><code>1bd1f01</code></a>
Ship partial-prerendering APIs to Canary (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34633">#34633</a>)</li>
<li><a
href="2f0649a0b2"><code>2f0649a</code></a>
[Fizz] Remove <code>nonce</code> option from resume-and-prerender APIs
(<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34664">#34664</a>)</li>
<li><a
href="5667a41fe4"><code>5667a41</code></a>
Bump next prerelease version numbers (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34639">#34639</a>)</li>
<li><a
href="e08f53b182"><code>e08f53b</code></a>
Match <code>react-dom/static</code> test entrypoints and published
entrypoints (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34599">#34599</a>)</li>
<li><a
href="8bb7241f4c"><code>8bb7241</code></a>
Bump useEffectEvent to Canary (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34610">#34610</a>)</li>
<li><a
href="83c88ad470"><code>83c88ad</code></a>
Handle fabric root level fragment with compareDocumentPosition (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34533">#34533</a>)</li>
<li><a
href="68f00c901c"><code>68f00c9</code></a>
Release Activity in Canary (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34374">#34374</a>)</li>
<li><a
href="3168e08f83"><code>3168e08</code></a>
[flags] enable opt-in for enableDefaultTransitionIndicator (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/34373">#34373</a>)</li>
<li><a
href="3434ff4f4b"><code>3434ff4</code></a>
Add scrollIntoView to fragment instances (<a
href="https://github.com/facebook/react/tree/HEAD/packages/react-dom/issues/32814">#32814</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/facebook/react/commits/v19.2.0/packages/react-dom">compare
view</a></li>
</ul>
</details>
<br />

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

Updates `react-router` from 7.9.3 to 7.9.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/releases">react-router's
releases</a>.</em></p>
<blockquote>
<h2>v7.9.4</h2>
<p>See the changelog for release notes: <a
href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v794">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v794</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md">react-router's
changelog</a>.</em></p>
<blockquote>
<h2>7.9.4</h2>
<h3>Patch Changes</h3>
<ul>
<li>
<p>handle external redirects in from server actions (<a
href="https://redirect.github.com/remix-run/react-router/pull/14400">#14400</a>)</p>
</li>
<li>
<p>New (unstable) <code>useRoute</code> hook for accessing data from
specific routes (<a
href="https://redirect.github.com/remix-run/react-router/pull/14407">#14407</a>)</p>
<p>For example, let's say you have an <code>admin</code> route somewhere
in your app and you want any child routes of <code>admin</code> to all
have access to the <code>loaderData</code> and <code>actionData</code>
from <code>admin.</code></p>
<pre lang="tsx"><code>// app/routes/admin.tsx
import { Outlet } from &quot;react-router&quot;;
<p>export const loader = () =&gt; ({ message: &quot;Hello, loader!&quot;
});</p>
<p>export const action = () =&gt; ({ count: 1 });</p>
<p>export default function Component() {<br />
return (<br />
&lt;div&gt;<br />
{/* ... <em>/}<br />
&lt;Outlet /&gt;<br />
{/</em> ... */}<br />
&lt;/div&gt;<br />
);<br />
}<br />
</code></pre></p>
<p>You might even want to create a reusable widget that all of the
routes nested under <code>admin</code> could use:</p>
<pre lang="tsx"><code>import { unstable_useRoute as useRoute } from
&quot;react-router&quot;;
<p>export function AdminWidget() {<br />
// How to get <code>message</code> and <code>count</code> from
<code>admin</code> route?<br />
}<br />
</code></pre></p>
<p>In framework mode, <code>useRoute</code> knows all your app's routes
and gives you TS errors when invalid route IDs are passed in:</p>
<pre lang="tsx"><code>export function AdminWidget() {
  const admin = useRoute(&quot;routes/dmin&quot;);
  //                      ^^^^^^^^^^^
}
</code></pre>
<p><code>useRoute</code> returns <code>undefined</code> if the route is
not part of the current page:</p>
<pre lang="tsx"><code></code></pre>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e650acfa72"><code>e650acf</code></a>
chore: Update version for release (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14431">#14431</a>)</li>
<li><a
href="7a2271e916"><code>7a2271e</code></a>
chore: Update version for release (pre) (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14427">#14427</a>)</li>
<li><a
href="f46c83c197"><code>f46c83c</code></a>
Merge branch 'main' into release-next</li>
<li><a
href="45bad2be88"><code>45bad2b</code></a>
unstable_useRoute (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14407">#14407</a>)</li>
<li><a
href="19ac8db0e8"><code>19ac8db</code></a>
fix(docs): correct unclosed Route tag in JSX example (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14406">#14406</a>)</li>
<li><a
href="850bf9a230"><code>850bf9a</code></a>
fix: handle rsc external redirects (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14400">#14400</a>)</li>
<li><a
href="2b592a39ff"><code>2b592a3</code></a>
chore: format</li>
<li><a
href="4ec4999206"><code>4ec4999</code></a>
chore: format</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router@7.9.4/packages/react-router">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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-18 13:40:55 +00:00
dependabot[bot]
f25195f6cf build(deps): bump roxmltree from 0.20.0 to 0.21.1 in /rust (#10827)
Bumps [roxmltree](https://github.com/RazrFalcon/roxmltree) from 0.20.0
to 0.21.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/RazrFalcon/roxmltree/blob/master/CHANGELOG.md">roxmltree's
changelog</a>.</em></p>
<blockquote>
<h2>[0.21.1] - 2025-10-09</h2>
<h3>Fixed</h3>
<ul>
<li>Remove implict <code>'static</code> lifetime bound on
<code>EntityResolver</code> dyn trait type alias.</li>
<li>Upgrade <code>EntityResolver</code> dyn trait type alias from
<code>FnMut</code> to <code>Fn</code> to resolve lifetime issues.</li>
</ul>
<h2>[0.21.0] - 2025-10-04</h2>
<h3>Added</h3>
<ul>
<li><code>ParsingOptions::entity_resolver</code> can be used to resolve
external entities referenced via public ID and URI.</li>
</ul>
<h3>Changed</h3>
<ul>
<li><code>Node::has_attribute</code>, <code>Node::attribute</code> and
<code>Node::attribute_node</code> match local names similar to how
<code>Node::has_tag_name</code> works.</li>
<li>Various internal performance improvements, e.g. devirtualization of
token dispatch and usage of <code>memchr</code> for finding
delimiters.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Possible panic when entity resolution yields unbalanced tags.</li>
<li>Quadratic runtime when merging consecutive text nodes.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="67644e16f4"><code>67644e1</code></a>
Also upgrade it from FnMut to Fn as borrowing entities from elsewhere
wont wo...</li>
<li><a
href="cfc15b7811"><code>cfc15b7</code></a>
Fix implicit 'static bound on EntityResolve dyn trait type alias.</li>
<li><a
href="cd5b0e80f4"><code>cd5b0e8</code></a>
Fix benchmark build, update changelog and bump version.</li>
<li><a
href="634f4d0047"><code>634f4d0</code></a>
Add support for resolving external entities</li>
<li><a
href="a1bd711620"><code>a1bd711</code></a>
Adjust attribute accessors to match purely on local names</li>
<li><a
href="5528680688"><code>5528680</code></a>
Fix lints emitted by current nightly Clippy.</li>
<li><a
href="d2c7801624"><code>d2c7801</code></a>
Speed-up attribute parsing by splitting tokenizing and verification</li>
<li><a
href="239114a9c2"><code>239114a</code></a>
Add benchmark using gigantic SVG containing huge attribute values.</li>
<li><a
href="3b0944785e"><code>3b09447</code></a>
Avoid quadratic runtime when merging text nodes</li>
<li><a
href="6df398d804"><code>6df398d</code></a>
Refine and extend synthetic benchmarks stressing CDATA, text and
attribute va...</li>
<li>Additional commits viewable in <a
href="https://github.com/RazrFalcon/roxmltree/compare/v0.20.0...v0.21.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=roxmltree&package-manager=cargo&previous-version=0.20.0&new-version=0.21.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-18 12:50:47 +00:00
dependabot[bot]
934477d1f5 build(deps): bump the sentry group in /rust with 2 updates (#10825)
Bumps the sentry group in /rust with 2 updates:
[sentry](https://github.com/getsentry/sentry-rust) and
[sentry-tracing](https://github.com/getsentry/sentry-rust).

Updates `sentry` from 0.43.0 to 0.45.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-rust/releases">sentry's
releases</a>.</em></p>
<blockquote>
<h2>0.45.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>Add custom variant to <code>AttachmentType</code> that holds an
arbitrary String. (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/916">#916</a>)</li>
</ul>
<h2>0.44.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/914">#914</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>Breaking change: <code>sentry::integrations::log::LogFilter</code>
has been changed to a <code>bitflags</code> struct.</li>
<li>It's now possible to map a <code>log</code> record to multiple items
in Sentry by combining multiple log filters in the filter, e.g.
<code>log::Level::ERROR =&gt; LogFilter::Event |
LogFilter::Log</code>.</li>
<li>If using a custom <code>mapper</code> instead, it's possible to
return a
<code>Vec&lt;sentry::integrations::log::RecordMapping&gt;</code> to map
a <code>log</code> record to multiple items in Sentry.</li>
</ul>
</li>
</ul>
<h3>Behavioral changes</h3>
<ul>
<li>ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/915">#915</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>If the <code>logs</code> feature flag is enabled, the default Sentry
<code>log</code> logger now sends logs for all events at or above
INFO.</li>
</ul>
</li>
<li>ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/910">#910</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>This changes the default value of
<code>sentry::ClientOptions::enable_logs</code> to
<code>true</code>.</li>
<li>This simplifies the setup of Sentry structured logs by requiring
users to just add the <code>log</code> feature flag to the
<code>sentry</code> dependency to opt-in to sending logs.</li>
<li>When the <code>log</code> feature flag is enabled, the
<code>tracing</code> and <code>log</code> integrations will send
structured logs to Sentry for all logs/events at or above INFO level by
default.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md">sentry's
changelog</a>.</em></p>
<blockquote>
<h2>0.45.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>Add custom variant to <code>AttachmentType</code> that holds an
arbitrary String. (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/916">#916</a>)</li>
</ul>
<h2>0.44.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/914">#914</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>Breaking change: <code>sentry::integrations::log::LogFilter</code>
has been changed to a <code>bitflags</code> struct.</li>
<li>It's now possible to map a <code>log</code> record to multiple items
in Sentry by combining multiple log filters in the filter, e.g.
<code>log::Level::ERROR =&gt; LogFilter::Event |
LogFilter::Log</code>.</li>
<li>If using a custom <code>mapper</code> instead, it's possible to
return a
<code>Vec&lt;sentry::integrations::log::RecordMapping&gt;</code> to map
a <code>log</code> record to multiple items in Sentry.</li>
</ul>
</li>
</ul>
<h3>Behavioral changes</h3>
<ul>
<li>ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/915">#915</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>If the <code>logs</code> feature flag is enabled, the default Sentry
<code>log</code> logger now sends logs for all events at or above
INFO.</li>
</ul>
</li>
<li>ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/910">#910</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>This changes the default value of
<code>sentry::ClientOptions::enable_logs</code> to
<code>true</code>.</li>
<li>This simplifies the setup of Sentry structured logs by requiring
users to just add the <code>log</code> feature flag to the
<code>sentry</code> dependency to opt-in to sending logs.</li>
<li>When the <code>log</code> feature flag is enabled, the
<code>tracing</code> and <code>log</code> integrations will send
structured logs to Sentry for all logs/events at or above INFO level by
default.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="aa6d85b90f"><code>aa6d85b</code></a>
release: 0.45.0</li>
<li><a
href="b99eb46bcf"><code>b99eb46</code></a>
feat(types): Add custom variant to <code>AttachmentType</code> (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/916">#916</a>)</li>
<li><a
href="34b27b5ed3"><code>34b27b5</code></a>
Merge branch 'release/0.44.0'</li>
<li><a
href="eb108e858e"><code>eb108e8</code></a>
release: 0.44.0</li>
<li><a
href="900ffa495c"><code>900ffa4</code></a>
ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/910">#910</a>)</li>
<li><a
href="8af23eec27"><code>8af23ee</code></a>
ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/915">#915</a>)</li>
<li><a
href="3b78cf8653"><code>3b78cf8</code></a>
feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/914">#914</a>)</li>
<li><a
href="9ba9a6452d"><code>9ba9a64</code></a>
meta(vscode): Run <code>rust-analyzer</code> with all features (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/902">#902</a>)</li>
<li><a
href="750dec0162"><code>750dec0</code></a>
ci: integrate Sentry Prevent (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/911">#911</a>)</li>
<li><a
href="d9cdf34d3c"><code>d9cdf34</code></a>
Merge branch 'release/0.43.0'</li>
<li>See full diff in <a
href="https://github.com/getsentry/sentry-rust/compare/0.43.0...0.45.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `sentry-tracing` from 0.43.0 to 0.45.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-rust/releases">sentry-tracing's
releases</a>.</em></p>
<blockquote>
<h2>0.45.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>Add custom variant to <code>AttachmentType</code> that holds an
arbitrary String. (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/916">#916</a>)</li>
</ul>
<h2>0.44.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/914">#914</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>Breaking change: <code>sentry::integrations::log::LogFilter</code>
has been changed to a <code>bitflags</code> struct.</li>
<li>It's now possible to map a <code>log</code> record to multiple items
in Sentry by combining multiple log filters in the filter, e.g.
<code>log::Level::ERROR =&gt; LogFilter::Event |
LogFilter::Log</code>.</li>
<li>If using a custom <code>mapper</code> instead, it's possible to
return a
<code>Vec&lt;sentry::integrations::log::RecordMapping&gt;</code> to map
a <code>log</code> record to multiple items in Sentry.</li>
</ul>
</li>
</ul>
<h3>Behavioral changes</h3>
<ul>
<li>ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/915">#915</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>If the <code>logs</code> feature flag is enabled, the default Sentry
<code>log</code> logger now sends logs for all events at or above
INFO.</li>
</ul>
</li>
<li>ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/910">#910</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>This changes the default value of
<code>sentry::ClientOptions::enable_logs</code> to
<code>true</code>.</li>
<li>This simplifies the setup of Sentry structured logs by requiring
users to just add the <code>log</code> feature flag to the
<code>sentry</code> dependency to opt-in to sending logs.</li>
<li>When the <code>log</code> feature flag is enabled, the
<code>tracing</code> and <code>log</code> integrations will send
structured logs to Sentry for all logs/events at or above INFO level by
default.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md">sentry-tracing's
changelog</a>.</em></p>
<blockquote>
<h2>0.45.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>Add custom variant to <code>AttachmentType</code> that holds an
arbitrary String. (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/916">#916</a>)</li>
</ul>
<h2>0.44.0</h2>
<h3>Breaking changes</h3>
<ul>
<li>feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/914">#914</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>Breaking change: <code>sentry::integrations::log::LogFilter</code>
has been changed to a <code>bitflags</code> struct.</li>
<li>It's now possible to map a <code>log</code> record to multiple items
in Sentry by combining multiple log filters in the filter, e.g.
<code>log::Level::ERROR =&gt; LogFilter::Event |
LogFilter::Log</code>.</li>
<li>If using a custom <code>mapper</code> instead, it's possible to
return a
<code>Vec&lt;sentry::integrations::log::RecordMapping&gt;</code> to map
a <code>log</code> record to multiple items in Sentry.</li>
</ul>
</li>
</ul>
<h3>Behavioral changes</h3>
<ul>
<li>ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/915">#915</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>If the <code>logs</code> feature flag is enabled, the default Sentry
<code>log</code> logger now sends logs for all events at or above
INFO.</li>
</ul>
</li>
<li>ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/pull/910">#910</a>)
by <a href="https://github.com/lcian"><code>@​lcian</code></a>
<ul>
<li>This changes the default value of
<code>sentry::ClientOptions::enable_logs</code> to
<code>true</code>.</li>
<li>This simplifies the setup of Sentry structured logs by requiring
users to just add the <code>log</code> feature flag to the
<code>sentry</code> dependency to opt-in to sending logs.</li>
<li>When the <code>log</code> feature flag is enabled, the
<code>tracing</code> and <code>log</code> integrations will send
structured logs to Sentry for all logs/events at or above INFO level by
default.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="aa6d85b90f"><code>aa6d85b</code></a>
release: 0.45.0</li>
<li><a
href="b99eb46bcf"><code>b99eb46</code></a>
feat(types): Add custom variant to <code>AttachmentType</code> (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/916">#916</a>)</li>
<li><a
href="34b27b5ed3"><code>34b27b5</code></a>
Merge branch 'release/0.44.0'</li>
<li><a
href="eb108e858e"><code>eb108e8</code></a>
release: 0.44.0</li>
<li><a
href="900ffa495c"><code>900ffa4</code></a>
ref(logs): enable logs by default if logs feature flag is used (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/910">#910</a>)</li>
<li><a
href="8af23eec27"><code>8af23ee</code></a>
ref(log): send logs by default when logs feature flag is enabled (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/915">#915</a>)</li>
<li><a
href="3b78cf8653"><code>3b78cf8</code></a>
feat(log): support combined LogFilters and RecordMappings (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/914">#914</a>)</li>
<li><a
href="9ba9a6452d"><code>9ba9a64</code></a>
meta(vscode): Run <code>rust-analyzer</code> with all features (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/902">#902</a>)</li>
<li><a
href="750dec0162"><code>750dec0</code></a>
ci: integrate Sentry Prevent (<a
href="https://redirect.github.com/getsentry/sentry-rust/issues/911">#911</a>)</li>
<li><a
href="d9cdf34d3c"><code>d9cdf34</code></a>
Merge branch 'release/0.43.0'</li>
<li>See full diff in <a
href="https://github.com/getsentry/sentry-rust/compare/0.43.0...0.45.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-18 11:22:09 +00:00
dependabot[bot]
d850185309 build(deps): bump the tailwind group in /rust/gui-client with 3 updates (#10832)
Bumps the tailwind group in /rust/gui-client with 3 updates:
[@tailwindcss/cli](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-cli),
[@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)
and
[tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss).

Updates `@tailwindcss/cli` from 4.1.13 to 4.1.14
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases"><code>@​tailwindcss/cli</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.14</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md"><code>@​tailwindcss/cli</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>[4.1.14] - 2025-10-01</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b67cbcf6cc"><code>b67cbcf</code></a>
Prepare v4.1.14 release (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-cli/issues/19037">#19037</a>)</li>
<li><a
href="ee1c7a69dc"><code>ee1c7a6</code></a>
Fix CLI watcher cleanup race (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-cli/issues/18905">#18905</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.1.14/packages/@tailwindcss-cli">compare
view</a></li>
</ul>
</details>
<br />

Updates `@tailwindcss/vite` from 4.1.13 to 4.1.14
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/releases"><code>@​tailwindcss/vite</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v4.1.14</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md"><code>@​tailwindcss/vite</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>[4.1.14] - 2025-10-01</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b67cbcf6cc"><code>b67cbcf</code></a>
Prepare v4.1.14 release (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/19037">#19037</a>)</li>
<li><a
href="5a94f81e7e"><code>5a94f81</code></a>
Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite/issues/18948">#18948</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.1.14/packages/@tailwindcss-vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `tailwindcss` from 4.1.13 to 4.1.14
<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.1.14</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</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.1.14] - 2025-10-01</h2>
<h3>Fixed</h3>
<ul>
<li>Handle <code>'</code> syntax in ClojureScript when extracting
classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18888">#18888</a>)</li>
<li>Handle <code>@variant</code> inside <code>@custom-variant</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18885">#18885</a>)</li>
<li>Merge suggestions when using <code>@utility</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18900">#18900</a>)</li>
<li>Ensure that file system watchers created when using the CLI are
always cleaned up (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18905">#18905</a>)</li>
<li>Do not generate <code>grid-column</code> utilities when configuring
<code>grid-column-start</code> or <code>grid-column-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Do not generate <code>grid-row</code> utilities when configuring
<code>grid-row-start</code> or <code>grid-row-end</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18907">#18907</a>)</li>
<li>Prevent duplicate CSS when overwriting a static utility with a theme
key (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18056">#18056</a>)</li>
<li>Show Lightning CSS warnings (if any) when optimizing/minifying (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18918">#18918</a>)</li>
<li>Use <code>default</code> export condition for
<code>@tailwindcss/vite</code> (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18948">#18948</a>)</li>
<li>Re-throw errors from PostCSS nodes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18373">#18373</a>)</li>
<li>Detect classes in markdown inline directives (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18967">#18967</a>)</li>
<li>Ensure files with only <code>@theme</code> produce no output when
built (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18979">#18979</a>)</li>
<li>Support Maud templates when extracting classes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18988">#18988</a>)</li>
<li>Upgrade: Do not migrate <code>variant = 'outline'</code> during
upgrades (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/18922">#18922</a>)</li>
<li>Upgrade: Show version mismatch (if any) when running upgrade tool
(<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19028">#19028</a>)</li>
<li>Upgrade: Ensure first class inside <code>className</code> is
migrated (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
<li>Upgrade: Migrate classes inside <code>*ClassName</code> and
<code>*Class</code> attributes (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss/pull/19031">#19031</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b67cbcf6cc"><code>b67cbcf</code></a>
Prepare v4.1.14 release (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19037">#19037</a>)</li>
<li><a
href="cc8fefc154"><code>cc8fefc</code></a>
Update magic-string to version 0.30.19</li>
<li><a
href="210575a6a5"><code>210575a</code></a>
Update dedent 1.6.0 → 1.7.0 (minor) (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/19010">#19010</a>)</li>
<li><a
href="c6e0a55d36"><code>c6e0a55</code></a>
Ensure files with only <code>@theme</code> produce no output when built
(<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18979">#18979</a>)</li>
<li><a
href="9a5bae2038"><code>9a5bae2</code></a>
Revert &quot;Update all pnpm dependencies (2025-09-20) (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18971">#18971</a>)&quot;</li>
<li><a
href="42eadfd1ee"><code>42eadfd</code></a>
Update all pnpm dependencies (2025-09-20) (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18971">#18971</a>)</li>
<li><a
href="c2aab49c77"><code>c2aab49</code></a>
Bump Prettier (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18960">#18960</a>)</li>
<li><a
href="d1fd645beb"><code>d1fd645</code></a>
Proposal: Allow overwriting static utilities that have a namespace (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18056">#18056</a>)</li>
<li><a
href="340b59dcde"><code>340b59d</code></a>
Do not generate <code>grid-column</code> when configuring
<code>grid-column-start</code> or `grid-c...</li>
<li><a
href="b7c7e48c5d"><code>b7c7e48</code></a>
Add <code>@container-size</code> utility (<a
href="https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss/issues/18901">#18901</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tailwindlabs/tailwindcss/commits/v4.1.14/packages/tailwindcss">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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-18 10:52:03 +00:00
dependabot[bot]
f90debb9fd build(deps): bump socket2 from 0.6.0 to 0.6.1 in /rust (#10826)
Bumps [socket2](https://github.com/rust-lang/socket2) from 0.6.0 to
0.6.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md">socket2's
changelog</a>.</em></p>
<blockquote>
<h1>0.6.1</h1>
<h2>Added</h2>
<ul>
<li>Added support for Windows Registered I/O (RIO)
(<a
href="https://redirect.github.com/rust-lang/socket2/pull/604">rust-lang/socket2#604</a>).</li>
<li>Added support for <code>TCP_NOTSENT_LOWAT</code> on Linux via
<code>Socket::(set_)tcp_notsent_lowat</code>
(<a
href="https://redirect.github.com/rust-lang/socket2/pull/611">rust-lang/socket2#611</a>).</li>
<li>Added support for <code>SO_BUSY_POLL</code> on Linux via
<code>Socket::set_busy_poll</code>
(<a
href="https://redirect.github.com/rust-lang/socket2/pull/607">rust-lang/socket2#607</a>).</li>
<li><code>SockFilter::new</code> is now a const function
(<a
href="https://redirect.github.com/rust-lang/socket2/pull/609">rust-lang/socket2#609</a>).</li>
</ul>
<h2>Changed</h2>
<ul>
<li>Updated the windows-sys dependency to version 0.60
(<a
href="https://redirect.github.com/rust-lang/socket2/pull/605">rust-lang/socket2#605</a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d0ba3d39a6"><code>d0ba3d3</code></a>
Release v0.6.1</li>
<li><a
href="3a8b7edda3"><code>3a8b7ed</code></a>
Add example to create <code>SockAddr</code> from
<code>libc::sockaddr_storage</code> (<a
href="https://redirect.github.com/rust-lang/socket2/issues/615">#615</a>)</li>
<li><a
href="b54e2e6dbf"><code>b54e2e6</code></a>
Disable armv7-sony-vita-newlibeabihf CI check</li>
<li><a
href="2d4a2f7b3b"><code>2d4a2f7</code></a>
Update feature <code>doc_auto_cfg</code> to <code>doc_cfg</code></li>
<li><a
href="11aa1029f2"><code>11aa102</code></a>
Add missing components when installing Rust in CI</li>
<li><a
href="528ba2b0da"><code>528ba2b</code></a>
Add TCP_NOTSENT_LOWAT socketopt support</li>
<li><a
href="1fdd2938c1"><code>1fdd293</code></a>
Correct rename in CHANGELOG.md (<a
href="https://redirect.github.com/rust-lang/socket2/issues/610">#610</a>)</li>
<li><a
href="600ff0d246"><code>600ff0d</code></a>
Add support for Windows Registered I/O</li>
<li><a
href="f0836965a1"><code>f083696</code></a>
Allow <code>SockFilter::new</code> in const contexts</li>
<li><a
href="15ade5100c"><code>15ade51</code></a>
Refactor for cargo fmt</li>
<li>Additional commits viewable in <a
href="https://github.com/rust-lang/socket2/compare/v0.6.0...v0.6.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=socket2&package-manager=cargo&previous-version=0.6.0&new-version=0.6.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-18 10:50:34 +00:00
Thomas Eizinger
6e2be658b0 chore(gateway): log unroutable packets only on DEBUG (#10897)
Currently, the Gateway logs all kinds of errors during packet processing
on WARN. Whilst it is generally good to be aware of warnings / errors,
some of these scenarios are particularly noisy. For various reasons, we
may not be able to route a packet arriving from the TUN device.

In such cases, we now return an `UnroutablePacket` error to the
event-loop which is special-cased to only log on DEBUG. It also includes
the 5 tuple as variables, which should make log analysis a bit easier if
we want to filter on specific parts of the 5 tuple.
2025-11-18 04:23:14 +00:00
Thomas Eizinger
663f23e9fb fix(connlib): classify WireGuard first (#10890)
WireGuard packets can have all kinds of byte-patterns at the very front
of the packet. Thus, we need to first check if a payload is a WireGuard
packet before attempting to classify it as anything else.

This function is currently only used for logging purposes. `snownet` has
its own logic for de-multiplexing and classifying packets.
2025-11-16 23:57:04 +00:00
Thomas Eizinger
7e5994b3c6 chore: bump to upstream proptest (#10888)
The changes from our fork have been upstreamed successfully. We can
therefore switch our dependency back to that.
2025-11-16 23:53:56 +00:00
Thomas Eizinger
ed6e2a4e7d feat(connlib): introduce DoHUrl abstraction (#10881)
When connlib processes DoH queries, we need to pass the server's URL
around a lot. In order to bootstrap the HTTP client, we need to extract
the host part of this URL and resolve it for IP addresses using the
system resolver. A regular URL doesn't necessarily have a host: It could
be relative. This creates an error path within our code that _should_
never get hit for DoH URLs as those are always absolute.

To avoid this error path, we follow the "parse, don't validate" approach
typical among strongly typed languages. We create our own type that can
only be constructed from absolute URLs. If we receive a URL from the
portal that is not absolute, we already fail at the deserialization
step. Using data privacy of the encapsulated url, we can then guarantee
that the host-part of the URL is always there and can access it in an
infallible way.

Given that we are now already parsing the URL to begin with, I've also
opted to directly implement an optimisation where we create a fast-path
for the 4 known DoH providers that we have which allows us to pass them
around and copy them without incurring extra allocations.

Finally, this custom type also comes with its own Display/Debug
implementation, making the log output a bit easier to read.
2025-11-16 23:38:06 +00:00
dependabot[bot]
c523add895 build(deps): bump zip from 5.1.1 to 6.0.0 in /rust (#10829)
Bumps [zip](https://github.com/zip-rs/zip2) from 5.1.1 to 6.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/zip-rs/zip2/releases">zip's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h3><!-- raw HTML omitted -->🐛 Bug Fixes</h3>
<ul>
<li>panic when reading empty extended-timestamp field (<a
href="https://redirect.github.com/zip-rs/zip2/pull/404">#404</a>) (<a
href="https://redirect.github.com/zip-rs/zip2/pull/422">#422</a>)</li>
<li>Restore original file timestamp when unzipping with
<code>chrono</code> (<a
href="https://redirect.github.com/zip-rs/zip2/pull/46">#46</a>)</li>
</ul>
<h3><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h3>
<ul>
<li>Configure Amazon Q rules (<a
href="https://redirect.github.com/zip-rs/zip2/pull/421">#421</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/zip-rs/zip2/blob/master/CHANGELOG.md">zip's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/zip-rs/zip2/compare/v5.1.1...v6.0.0">6.0.0</a>
- 2025-10-09</h2>
<h3><!-- raw HTML omitted -->🚀 Features</h3>
<ul>
<li>Add by_index_with_options(), which can be used to ignore encryption
in a file's metadata (<a
href="https://redirect.github.com/zip-rs/zip2/pull/439">#439</a>) and
may be used for other file-specific overrides in the future.</li>
</ul>
<h3><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h3>
<ul>
<li>[<strong>breaking</strong>] <code>FileOptions::add_extra_data</code>
is now generic and accepts any <code>AsRef&lt;[u8]&gt;</code>. (<a
href="https://redirect.github.com/zip-rs/zip2/issues/435">#435</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="abfc23d19e"><code>abfc23d</code></a>
feat: Upgrade [Extended]FileOptions::add_extra_data() data from
Box&lt;[u8]&gt; to ...</li>
<li><a
href="eb1b586d0e"><code>eb1b586</code></a>
docs: Update zip_writer documentation example (<a
href="https://redirect.github.com/zip-rs/zip2/issues/431">#431</a>)</li>
<li><a
href="26e6e08e70"><code>26e6e08</code></a>
feat: Add by_index_with_options() for ignoring encryption (<a
href="https://redirect.github.com/zip-rs/zip2/issues/439">#439</a>)</li>
<li><a
href="165415d7e2"><code>165415d</code></a>
chore(deps): update nt-time requirement from 0.10.6 to 0.12.1 (<a
href="https://redirect.github.com/zip-rs/zip2/issues/429">#429</a>)</li>
<li><a
href="1d5d4edf6c"><code>1d5d4ed</code></a>
chore(deps): update lzma-rust2 requirement from 0.13 to 0.14 (<a
href="https://redirect.github.com/zip-rs/zip2/issues/432">#432</a>)</li>
<li><a
href="72cce40def"><code>72cce40</code></a>
chore(deps): update nt-time requirement from 0.10.6 to 0.12.1 (<a
href="https://redirect.github.com/zip-rs/zip2/issues/428">#428</a>)</li>
<li><a
href="2ef4d3e549"><code>2ef4d3e</code></a>
chore(deps): update nt-time requirement from 0.10.6 to 0.12.1 (<a
href="https://redirect.github.com/zip-rs/zip2/issues/427">#427</a>)</li>
<li><a
href="9cf28cb6c0"><code>9cf28cb</code></a>
test(ci): Fix: <code>rename</code> can't be skipped</li>
<li><a
href="5987cdd709"><code>5987cdd</code></a>
test(ci): Fix: need recursive rename</li>
<li><a
href="74f8a3c189"><code>74f8a3c</code></a>
test(ci): Need to rename more files during fuzz runs</li>
<li>Additional commits viewable in <a
href="https://github.com/zip-rs/zip2/compare/v5.1.1...v6.0.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=zip&package-manager=cargo&previous-version=5.1.1&new-version=6.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-15 07:46:37 +00:00
Thomas Eizinger
95fdb7f62a fix(connlib): sanitize resolvers before re-resolving portal URL (#10880)
In #10817, connlib gained the ability to re-resolve the portal's
hostname on WebSocket connection hiccups. The list of upstream servers
used for that may contain sentinel DNS server IPs on certain systems if
connlib's DNS control is currently active. Connlib filters these servers
internally before computing the effective list of upstream servers.

The DNS client used by the event-loop contacts all servers in the list
but waits for at most 2s before merging all received records together.
If there are upstream DNS servers defined in the portal and those are
also resources which we are currently not connected to, querying these
servers would trigger a message to the portal, forming a circular
dependency. This circular dependency is only broken by the 2s timeout.
Whilst not fatal for connlib's functionality, it means that in such a
situation, reconnecting to the portal always has to wait for this
timeout.

To fix this, we first apply the system DNS resolvers to connlib and only
pass the now returned sanitized list on to the DNS client.

Related: #10854

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thomaseizinger <5486389+thomaseizinger@users.noreply.github.com>
2025-11-15 05:47:43 +00:00
Thomas Eizinger
33bd31c1eb chore(connlib): pass through DoH servers to DNS config (#10872)
This is a follow-up to #10851.

In order to be able to use and reason about the DoH servers, we need to
deserialize the list and pass the servers into connlib's `DnsConfig`.
Right now, they just sit there and we don't do anything with them. Thus,
this PR is save to go into `main`, even if we were to make a release
before our DoH support is fully finished.

To ensure this is the case, we also update the proptests in this PR to
randomly sample and apply DoH servers.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-13 22:37:30 +00:00
Thomas Eizinger
d282b641c5 refactor(connlib): use anyhow::Error for recursive DNS (#10871)
With the introduction of DoH, we will need a more advanced error type
for recursive DNS responses. In particular, a DoH query might fail
because the underlying TCP connection got closed. With #10856, the HTTP
client no longer supports retries but instead needs to be recreated.

In order to accurately detect this failure case, we need `anyhow`'s
downcasting abilities.

This PR prepares the already existing code for that by switching from
`io::Error` to `anyhow::Error`.
2025-11-13 20:37:54 +00:00
Thomas Eizinger
1a5c40bd75 refactor(connlib): extract l4-udp-dns-client (#10854)
In order to bootstrap DoH servers, we need a way of reliably resolving
the domain of the DoH server to an IP address. Initially, I thought that
this would be tricky to do if we have to integrate this into the
Client's state machine.

Whilst implementing DoH however, I realised that we can instead put this
responsibility onto the IO layer of connlib. Similar to other cases, we
can reuse external triggers as our retry mechanism in case of failure.
In particular, we can simply issue UDP DNS queries for the DoH domain to
all system-defined DNS resolvers every time we are told to send a DNS
query over DoH but the corresponding client isn't initialized yet.

In other words, instead of building a retry mechanism ourselves, we
attempt to repair any kind of broken state once per DNS query that we
receive.

Performing this DNS resolution does require a bit of code. We already
started to do something similar in #10817. In order to reuse that code,
we extract it into a `l4-udp-dns-client` crate and slightly refactor its
semantics. In particular, we now wait for the response of all upstream
servers (but at most 2s) and combine the result.

The resulting `UdpDnsClient` can now be used inside the Client's
event-loop to re-resolve the portal URL and will also be used as part of
our DoH implementation to bootstrap the connection to the DoH server.

Related: #4668
2025-11-13 13:19:22 +00:00
Thomas Eizinger
ff3ff93e1a fix(dns-types): use base64url encoding without padding (#10875)
According to the DoH spec, the base64url encoded query must not include
any padding characters.
2025-11-13 12:48:21 +00:00
Thomas Eizinger
81023dbf52 feat(connlib): make parallel requests with HttpClient (#10856)
Our `socket-factory`-aware HttpClient is currently only able to handle a
single request at a time. That is a result of the requirement that we
wanted to support connections to different domains but also be able to
"self-heal" those connections by establishing a new one if the current
one failed.

As I am learning more about how connlib's DoH support is going to work,
it became apparent that we will only ever need to connect to a single
domain per instance of the `HttpClient`. In addition, it is quite
important to allow for concurrent requests: We don't want to process DoH
queries in sequence but instead make full use of the underlying HTTP2
protocol and send multiple requests in parallel.

This PR refactors the `HttpClient` (which isn't in use anywhere yet) to
only support a single connection per instance. That connection is
established when the instance is created. This is also conceptually
easier to understand as we only manage a single connection without
mutable state.

Related: #4668
2025-11-13 12:47:38 +00:00
Thomas Eizinger
53113c645f fix(connlib): don't panic in fallible function (#10874)
Panicking - even though it is unlikely to happen here - is unnecessary
because we can simply return an error instead.
2025-11-13 12:35:28 +00:00
Thomas Eizinger
cd650de1f8 refactor: prepare client init for upstream DoH servers (#10851)
In order to support multiple different protocols of upstream DNS
resolvers, we deprecate the `upstream_dns` field in the client's `init`
message and introduce two new fields:

- `upstream_do53`
- `upstream_doh`

For now, only `upstream_do53` is populated and `upstream_doh` is always
empty.

On the client-side, we for now only introduce the `upstream_do53` field
but fall-back to `upstream_dns` if that one is empty. This makes this PR
backwards-compatible with the portal version that is currently deployed
in production. Thus, this PR can be merged even prior to deploying the
portal.

Internally, we prepare connlib's abstractions to deal with different
kinds of upstreams by renaming all existing "upstream DNS" references to
`upstream_do53`: DNS over port 53. That includes UDP as well as TCP DNS
resolution.

Resolves: #10791

---------

Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-11-12 05:40:58 +00:00
dependabot[bot]
4bd768aed5 build(deps): bump @types/node from 24.5.2 to 24.7.2 in /rust/gui-client (#10834)
Bumps
[@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)
from 24.5.2 to 24.7.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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=24.5.2&new-version=24.7.2)](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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-12 04:35:22 +00:00
Thomas Eizinger
8af8978ad5 chore(connlib): include "packet kind" in decapsulation errors (#10867)
When looking at error logs from Gateways or Clients, it can be useful to
know, what kind of packet we failed to process.
2025-11-12 04:26:20 +00:00
Thomas Eizinger
ee38ccc120 chore(connlib): log index of failed connections (#10866)
Logging the peer index of a failed connection makes it easier to
correlate it with logs when we receive packets for an unknown
connection.
2025-11-12 03:37:39 +00:00
Thomas Eizinger
32e1c088e7 chore(gateway): include domain in "not allowed" log (#10863)
The resource could be a wildcard DNS resource. It is useful to know,
which particular domain the client tried to access.
2025-11-12 03:37:03 +00:00
Thomas Eizinger
5f61eaf8f2 feat(connlib): encode and decode DoH messages (#10857)
In order to support DoH, we need to be able to encode and decode DNS
queries and responses from and to HTTP requests and responses. We
therefore extend your `dns-types` crate with the required functionality.

The [RFC8484](https://datatracker.ietf.org/doc/html/rfc8484) provides us
with two test vectors that we can test against.

Related: #4668

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thomaseizinger <5486389+thomaseizinger@users.noreply.github.com>
2025-11-11 15:27:25 +00:00
Thomas Eizinger
cf14a8694c fix(connlib): use system DNS resolvers to re-resolve portal URL (#10853)
In #10817, we landed a fix that allows Clients to re-resolve the portal
URL every time the WebSocket connection fails. Currently, we use the
active upstream resolvers for this.

This can lead to a kind of deadlock in case the upstream resolver is a
CIDR resource that we are not yet connected to. In that case, we'd need
a connection to the portal to establish a connection to the Gateway.

By always using the system resolvers for this, we avoid this circular
dependency.
2025-11-11 07:50:26 +00:00
Thomas Eizinger
3e849ae852 fix(gui-client): use Wayland rendering backend on Linux (#10849)
Previously, we opted into the X11 GTK backend when rendering the GUI
Client's window. This is causing issues on newer Linux distributions
such as Fedora 43 where Wayland is now the only available compositor.

Removing the X11 GTK requires us to draw our own CSDs such as titlebars
and a close button. This PR does exactly that by adding a minimalistic
title bar. To make better use of the space, we move the section headers
into there.

|Before|After|
|---|---|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-11"
src="https://github.com/user-attachments/assets/9439a69b-65ba-41d6-b1f8-4448e0f80728"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-55"
src="https://github.com/user-attachments/assets/7884b2cc-3d9c-4b47-9a1e-c6462aef36ab"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-16"
src="https://github.com/user-attachments/assets/2cfea825-5c08-45a5-873c-5afcbc1dbf16"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-40-58"
src="https://github.com/user-attachments/assets/43ddd7c9-ce65-42f7-b972-28c6b172b70d"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-19"
src="https://github.com/user-attachments/assets/446873a7-9023-4266-9377-ea7b8b4353ee"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-01"
src="https://github.com/user-attachments/assets/64439383-f33f-461d-9b4a-6b4138bd675b"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-22"
src="https://github.com/user-attachments/assets/6c39e06c-1d77-471f-91f1-32a78b90a21c"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-04"
src="https://github.com/user-attachments/assets/b56912cb-9c85-4b5a-9295-dae6139b25c6"
/>|
|<img width="1900" height="1174" alt="Screenshot From 2025-11-11
11-14-26"
src="https://github.com/user-attachments/assets/5a5d638c-15bf-4523-8466-2e0977a03e22"
/>|<img width="1800" height="1000" alt="Screenshot From 2025-11-11
11-41-06"
src="https://github.com/user-attachments/assets/ed169b52-ef86-4dc4-8f25-852da622eaa1"
/>|
2025-11-11 05:51:08 +00:00
Thomas Eizinger
0008539b65 refactor(connlib): use dedicated UDP DNS client (#10850)
By default, DNS queries are sent over UDP by most systems. UDP is an
easy to understand protocol because each packet stands by itself and at
least as far as UDP is concerned, the payload is contained within a
single packet.

In Firezone, we receive all DNS traffic on the TUN device as IP packets.
Processing the UDP packets is trivial as each query is contained within
a single IP packet. For TCP, we first need to assemble the TCP stream
before we can read the entire query.

In case a DNS query is not for a Firezone DNS resource, we want to
forward it to the specified upstream resolver, either directly from the
system or - in case the specified upstream resolver is an IP resource -
through the tunnel as an IP packet. Specifically, the forwarding of UDP
DNS packets through the tunnel currently happens like this:

IP packet -> read UDP payload -> parse DNS query -> mangle original
destination IP to new upstream -> send through tunnel

For TCP DNS queries, it is not quite as easy as we have to decode the
incoming TCP stream first before we can parse the DNS query. Thus, when
we want to then forward the query, we need to open our own TCP stream to
the upstream resolver and encode the DNS query onto that stream, sending
each IP packet from the TCP client through the tunnel.

The difference in these designs makes several code paths in connlib hard
to follow.

Therefore - and despite the simplicity of DNS over UDP - we already
created our own "Layer 3 UDP DNS"-client. This PR now integrates this
client into the tunnel. Using this new client, we can simplify the
processing of UDP DNS queries because we never have to "go back" to the
original IP packet. Instead, when a DNS query needs to be forwarded to
an usptream resolver through the tunnel, we simply tell the Layer 3 UDP
DNS client to make a new DNS query. The processing of the resulting IP
packet then happens in a different place, right next to where we also
process the IP packets of the TCP DNS client.

That simplifications unlocks further refactorings where we now only
process DNS queries in a single place and the transport we received it
over is a simple function parameter with the control flow for both of
them being identical.

Related: #4668
2025-11-11 03:53:25 +00:00
Thomas Eizinger
de7d3bff89 fix(connlib): re-resolve portal host on WS hiccup (#10817)
Currently, the DNS records for the portal's hostname are only resolved
during startup. When the WebSocket connection fails, we try to reconnect
but only with the IPs that we have previously resolved. If the local IP
stack changed since then or the hostname now points to different IPs, we
will run into the reconnect-timeout configured in `phoenix-channel`.

To fix this, we re-resolve the portal's hostname every time the
WebSocket connection fails. For the Gateway, this is easy as we can
simply reuse the already existing `TokioResolver` provided by hickory.
For the Client, we need to write our own DNS client on top of our socket
factory abstraction to ensure we don't create a routing loop with the
resulting DNS queries. To simplify things, we only send DNS queries over
UDP. Those are not guaranteed to succeed but given that we do this on
every "hiccup", we already have a retry mechanism. We use the currently
configured upstream DNS servers for this.

Resolves: #10238
2025-11-11 03:24:36 +00:00
dependabot[bot]
a9058c7f55 build(deps): bump known-folders from 1.3.1 to 1.4.0 in /rust (#10831)
Bumps [known-folders](https://github.com/artichoke/known-folders-rs)
from 1.3.1 to 1.4.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/artichoke/known-folders-rs/releases">known-folders's
releases</a>.</em></p>
<blockquote>
<h2>v1.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump thor from 1.3.2 to 1.4.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/85">artichoke/known-folders-rs#85</a></li>
<li>Bump rubocop from 1.77.0 to 1.79.1 in the bundler-deps group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/86">artichoke/known-folders-rs#86</a></li>
<li>Bump the gha-deps group with 3 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/87">artichoke/known-folders-rs#87</a></li>
<li>Use zizmor audit action by <a
href="https://github.com/lopopolo"><code>@​lopopolo</code></a> in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/88">artichoke/known-folders-rs#88</a></li>
<li>Bump rubocop from 1.79.1 to 1.81.1 in the bundler-deps group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/89">artichoke/known-folders-rs#89</a></li>
<li>Bump the gha-deps group with 5 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/91">artichoke/known-folders-rs#91</a></li>
<li>Relax windows-sys version requirement, prepare for v1.4.0 release by
<a href="https://github.com/lopopolo"><code>@​lopopolo</code></a> in <a
href="https://redirect.github.com/artichoke/known-folders-rs/pull/92">artichoke/known-folders-rs#92</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0">https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="69fd83233a"><code>69fd832</code></a>
Merge pull request <a
href="https://redirect.github.com/artichoke/known-folders-rs/issues/92">#92</a>
from artichoke/dev/lopopolo-windows-sys-bump</li>
<li><a
href="ff9e8f7f7c"><code>ff9e8f7</code></a>
working</li>
<li><a
href="d8f5cc7b1a"><code>d8f5cc7</code></a>
powershell</li>
<li><a
href="1ad9c0cd63"><code>1ad9c0c</code></a>
try again</li>
<li><a
href="4ee5739bb0"><code>4ee5739</code></a>
precise needs a fully formed version</li>
<li><a
href="039c0992a9"><code>039c099</code></a>
Merge pull request <a
href="https://redirect.github.com/artichoke/known-folders-rs/issues/91">#91</a>
from artichoke/dependabot/github_actions/gha-deps-f417...</li>
<li><a
href="8f8402d463"><code>8f8402d</code></a>
Use a valid spec</li>
<li><a
href="b0af2f35da"><code>b0af2f3</code></a>
address zizmor complaint</li>
<li><a
href="2281b61f94"><code>2281b61</code></a>
don't have to actually relax MSRV</li>
<li><a
href="dce5052821"><code>dce5052</code></a>
update CI</li>
<li>Additional commits viewable in <a
href="https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=known-folders&package-manager=cargo&previous-version=1.3.1&new-version=1.4.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-11 01:36:11 +00:00
dependabot[bot]
e9fcb20564 build(deps): bump nu-ansi-term from 0.50.1 to 0.50.3 in /rust (#10830)
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from
0.50.1 to 0.50.3.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/nushell/nu-ansi-term/commits">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nu-ansi-term&package-manager=cargo&previous-version=0.50.1&new-version=0.50.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 merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@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>
2025-11-11 01:35:25 +00:00
Thomas Eizinger
6e85638360 chore(connlib): silence hickory_resolver (#10848)
Logs from the `hickory_resolver` module are a bit noisy, so filter those
out from our logs.
2025-11-11 01:04:41 +00:00
Firezone Bot
5ae2707719 chore: publish gateway 1.4.18 (#10823) 2025-11-10 19:08:17 +11:00
Thomas Eizinger
3022c019e1 chore(connlib): set user.account_slug for Sentry logs (#10815)
By default, the Sentry SDK doesn't include custom user attributes when
it sends logs. To make viewing logs easier, we add the `account_slug`
attribute to all logs that are posted to Sentry.
2025-11-10 04:08:45 +00:00
Thomas Eizinger
166b0d1573 feat(linux): compute device ID from /etc/machine-id (#10805)
All of our Linux applications have a soft-dependency on systemd. That
is, in the default configuration, we expect systemd to be present on the
machine. The only exception here are the docker containers for Headless
Client and Gateway.

For the GUI client in particular, systemd is a hard-dependency in order
to control DNS on the system which we do via `systemd-resolved`. To
secure the communication between the GUI client and its tunnel process,
we automatically create a group called `firezone-client` to which the
user gets added. All members of the group are allowed to access the unix
socket which is used for IPC between the two processes. Membership in
this group is also a prerequisite for accessing any of the configuration
files.

On the first launch of the GUI client on a Linux system, this presents a
problem. For group membership changes to take the effect, the user needs
to reboot. We say that in the documentation but it is unclear whether
all users will read that thoroughly enough. To help the user, the GUI
client checks for membership of the current user in the group and alerts
the user via a dialog box if that isn't the case. This would all be fine
if it would actually work. Unfortunately, that check ends up being too
late in the process. If we aren't a member of the group, we cannot read
the device ID and bail early, thus never reaching the check and
terminating the process without any dialog box or user-visible error.

We could attempt to fix this by shuffling around some of the startup
init code. That is a sub-optimal solution however because it a) may get
broken again in the future and b) it means we have to delay
initialisation of telemetry until a much later point.

Given that this is only a problem on Linux, a better solution is to
simply not rely on the disk-based device ID at all. Instead, we can
integrate with systemd and deterministically derive a device ID from the
unique machine ID and a randomly chosen "app ID".

For backwards-compatibility reasons, the disk-based device ID is still
prioritised. For all new installs however, we will use the one based on
`/etc/machine-id`.
2025-11-10 02:29:52 +00:00
Thomas Eizinger
8651413a95 chore(gateway): downgrade warning if peer not found (#10814)
Logging this on WARN appears to be a bit excessive and there is not
really anything we can do about it.

Resolves: #10813
2025-11-10 01:45:50 +00:00
Thomas Eizinger
f4216710e0 fix(telemetry): don't append duplicate attributes in Sentry log (#10819)
When we are building the log message that is sent to Sentry, we append
several attributes to mimic the formatting that we get from
`tracing_subscriber::fmt`. To do that, we strip the span name from the
attribute which can result in us processing the same attribute such as
`cid` twice: Once from a span and once from the actual log message. In
order to not append the same message twice, we check for its presence in
the attributes map first.

This avoids having message in Sentry such as:

```
Sampled relay cid=c18e1da8-8ef8-4e11-a325-28d6b387d503 rid=3af15c76-9e84-46a6-90e1-63ecb2bc9f80 cid=c18e1da8-8ef8-4e11-a325-28d6b387d503
```
2025-11-10 01:42:01 +00:00
Thomas Eizinger
bc95a1f425 chore(snownet): log connection state on failure (#10820)
When investigating, why a connection fails it is useful to know right
away, what the last connection state was, including the kind of
connection, such as `PeerToPeer`, `RelayToPeer` etc.
2025-11-10 01:41:23 +00:00
Thomas Eizinger
123c5a5d97 chore(connlib): always include wire::api as Sentry breadcrumb (#10821)
Sentry appends "breadcrumbs" to every error that gets sent to the
backend. By default, those include the last 500 DEBUG logs. Our
`phoenix_channel` module logs the incoming and outgoing messages on
TRACE using the `wire::api::send` and `wire::api::recv` targets.

To make debugging these easier, we always include anything on
`wire::api` in the breadcrumbs.
2025-11-10 01:40:30 +00:00
Thomas Eizinger
74bd28d25a ci(gui-client): fix .deb test installation (#10816)
The current test installation fails because it is operating in a
headless environment without a display user. Some more testing of the
`who` command showed that we can simply take the first user. That avoids
`grep` which was previously failing with an exit code of 1, aborting the
installation because our `postinst` script has `pipefail` set.
2025-11-09 16:50:33 +00:00