Commit Graph
5803 Commits
Author SHA1 Message Date
Danielle Maywood 57dc47dc42 feat(site): migrate agent chat scrolling (#28130)
Replace the Agents chat's inverse scroll container and sticky
user-message overlays with the stock MessageScroller from
`@shadcn/react@0.3.0`.

Transcript rows now render as direct MessageScroller Items with stable
server-backed identities. Only the latest active user turn is a scroll
anchor, older history preserves the reading position when prepended, and
the package owns follow mode, prompt navigation, and the `Scroll to
bottom` control. The integration uses the upstream component hierarchy
without patches, bridges, or application-owned scroll correction.

Depends on #28079.

<details>
<summary>Implementation notes</summary>

- Use `MessageScroller.Provider`, `Root`, `Viewport`, `Content`, `Item`,
and `Button` directly.
- Keep durable row IDs stable across pagination; the live assistant uses
an ephemeral row until its durable message arrives.
- Load additional history from MessageScroller's start-edge state,
including underfilled transcripts and retry after a page error.
- Remove inverse scrolling, sticky message copies, scroll refs, forced
scroll commands, and `react-infinite-scroll-component`.

</details>

Generated by Coder Agents on behalf of @DanielleMaywood.
2026-08-14 12:59:19 +01:00
Danielle Maywood 7617b6bdcc refactor(site): render live assistant output as a chat timeline row (#28079)
Refactor the Agents chat timeline so live assistant output renders as a
timeline row through the same components as durable messages, ahead of
the stacked MessageScroller migration in #28130.

`ConversationTimeline`'s block rendering is extracted into
`MessageBlocks`, the streaming/durable assistant split collapses into a
shared `AssistantOutput`, and `LiveStreamTail` shrinks to the empty
state and terminal failure callout. Row keys are plain `message:<id>`
strings; the live assistant row is a separate ephemeral row. This PR
does not change scrolling behavior and adds no backend, API, or database
fields.

<details>
<summary>Implementation notes</summary>

- Extract `BlockList` and friends from `ConversationTimeline` into
`MessageBlocks` (pure move).
- Replace `StreamingOutput` with `AssistantOutput`, used for both live
and durable assistant rows.
- Render the live assistant as a timeline row via `assignTimelineRows`
instead of separate transient content below the transcript.
- Keep existing transcript grouping, prompt navigation, and the current
scroll container unchanged; the scroller swap happens in #28130.

</details>

Generated by Coder Agents on behalf of @DanielleMaywood.
2026-08-14 12:59:18 +01:00
Samuel Volin b26f4c0e03 feat: DEVEX-751 updated premiumpaywall component (#28070)
* implements the supergraphic component, to show a minified webp
theme-aware version of the supergraphic
* refine the PaywallPremium into separate PaywallSmall component
* paywall no long includes link to docs for component; will be part of
DEVEX-742
* appearance and custom roles page uses PaywallSmall

<img width="1509" height="676" alt="Screenshot 2026-08-12 at 7 49 54 AM"
src="https://github.com/user-attachments/assets/17cd1a16-acc8-415a-819d-bdb9259fdaf9"
/>
<img width="1499" height="702" alt="Screenshot 2026-08-11 at 12 46
55 PM"
src="https://github.com/user-attachments/assets/05cd628a-c8c1-4b1c-a4c9-318814eec428"
/>
<img width="1466" height="549" alt="Screenshot 2026-08-11 at 12 44
43 PM"
src="https://github.com/user-attachments/assets/f0bb0c0e-7702-41a0-a718-78a637c9f4e9"
/>
<img width="1715" height="652" alt="Screenshot 2026-08-12 at 11 25
21 AM"
src="https://github.com/user-attachments/assets/55dedd2c-d44c-4cd0-a425-fbde4452f622"
/>
2026-08-13 15:21:22 -06:00
McKayla はな e1fa247e59 feat: redirect to the template builder after first time setup (#27670) 2026-08-13 11:57:29 -06:00
Michael Suchacz bca5d72c1c fix(site): prefer permitted organization for chat creation (#28078)
Fixes first-send 403s for multi-org users who lack `chat:create` in the
deployment default organization (CODAGT-892). Two frontend defects
combined to send chat creation to the wrong organization:

1. The Agents create form initialized its organization selection
permission-blind to the default org and only corrected it when the
`permittedOrganizations` authcheck result *transitioned*, so a fast
first send raced the check, and on warm-query-cache remounts the
correction never ran at all: the wrong org stayed selected permanently
while the org picker was hidden.
2. The permitted-organizations authcheck itself sent no `owner_id`, so
roles that grant `chat:create` at member (owner) scope, such as
`agents-access` (Coder Agents User, the exact role in the customer
report), were denied in every organization and the form always fell back
to the default org. This part was split out and already landed on main
via #28076; after rebasing, this PR relies on that fix and keeps its
stricter regression stories around it.

## Changes

- Derive the effective organization at render time: keep the user's
explicit pick only while it is still permitted, otherwise fall back to
the permitted default org, then the first permitted org, then the
dashboard default. Replaces the transition-based reconciliation, which
could not fire when the query cache was already warm on mount.
- Keep user-driven org cleanup (workspace selection, attachments) in the
picker/dialog event handlers; permission-driven changes are handled by
render-time state adjustments and the attachment hook's post-commit
adoption effect.
- Disable Send until the permitted-organizations check settles and the
attachment hook has adopted the effective org; hide the org picker and
disable the workspace picker until the check settles (their
pre-settlement options come from the unfiltered dashboard fallback, so a
pick could persist a foreign-org workspace).
- Scope persisted attachments to their organization in
`useFileAttachments`: restoration defers until a permitted org is known,
permission-driven org changes replace attachment state post-commit,
in-flight uploads are invalidated by an adoption epoch (including
A-to-B-to-A round trips), and no render exposes another org's file IDs,
including when authorization resolves to no org at all.
- Revalidate org-scoped state on permission refetches: a revoked
explicit selection clears instead of lying latent, a settled
effective-org change drops the stored workspace, and the org-change
confirmation dialog closes (and re-checks on confirm) when its pending
org is revoked.
- Rebase reconciliation with #28076: the stories use its
`permittedOrganizationsKey` helper and retain its
`MemberScopedPermissionsShowOrgPicker` regression story alongside this
PR's stricter member-scope stories.

The backend RBAC rejection was correct; this is frontend-only.

## Testing

- Red-green: every guard above was verified by reverting it and
confirming exactly its guarding story or unit test fails (whole-file
runs).
- `pnpm -C site check`, `pnpm -C site lint`, `pnpm -C site lint:types`,
full `AgentCreateForm.stories.tsx` (42 pass),
`useFileAttachments.test.tsx` (8 pass), re-run after the rebase onto
main.
- Dogfood UAT on a licensed multi-org dev deployment at this branch: a
restricted user with `agents-access` only in a non-default org sends
first and warm-remount messages successfully (201, payload carries the
permitted org, no 403); admin picker, workspace filtering, and
attachment org-change dialog verified. Round 2 of UAT caught the missing
`owner_id` (now landed via #28076); round 3 re-verified end to end.

> Mux created this PR on Mike's behalf.
2026-08-13 18:30:22 +02:00
TJ 49cbd7dde3 fix(site): keep standard avatar border for normal AI spend state (#28037)
The navbar avatar received a grey `border-content-secondary` override
whenever AI spend data was present, so the default (normal spend) state
looked different from a standard avatar. It also relied entirely on
border color to communicate state, which is easy to miss and
inaccessible to colorblind users.

## Changes

- **Avatar border**: always standard — the severity border override is
removed for all states.
- **Warning / exceeded states** get a notification-style corner badge
(like the inbox unread badge):
- Warning: triangle-alert icon on the orange alert surface
(`surface-orange` / `highlight-orange`).
- Exceeded: octagon-alert icon on the red alert surface (`surface-red` /
`highlight-red`).
- Distinct icon shapes per state make the change perceivable without
relying on color; surface/highlight token pairs keep the icon light on
dark mode and dark on light mode.
- **Accessibility**: the trigger now has a descriptive accessible name —
`User menu`, `User menu. AI spend is nearing its limit`, or `User menu.
AI spend limit exceeded`.

Storybook: `AvatarBorderNormal/Warning/Exceeded` stories assert the
trigger's accessible name per state, and Chromatic snapshots cover the
visual states.

<img width="604" height="542" alt="image"
src="https://github.com/user-attachments/assets/3dab5700-c35b-44a6-abc5-7413254adeee"
/>


---
*This PR was generated by Coder Agents on behalf of @tracyjohnsonux.*
2026-08-13 07:20:40 -07:00
Susana Ferreira 2d9b6eda8f feat: add experimental CLI to price unpriced AI models (#27926)
## Description

AI Gateway computes the cost of an interception from `ai_model_prices`,
which is seeded on every server start from a price book embedded in the
binary. A model the price book does not cover records a NULL cost, so
its spend is invisible to cost reporting and is not enforced against
budgets. The only fix was to wait for a Coder release that added the
model.

This adds an experimental CLI, backed by an experimental HTTP endpoint,
for pricing those models. Models the price book already covers are
rejected, because the seeder re-applies the book on every start and
would overwrite an operator price. Support for custom pricing will be
handled in
https://linear.app/codercom/issue/AIGOV-589/extend-experimental-cli-command-to-set-custom-ai-model-prices.

## Commands

```
coder exp ai-model-prices list [--provider] [--model]
coder exp ai-model-prices update [file|-] [--provider] [--model] [--input-price] [--output-price] [--cache-read-price] [--cache-write-price] [--yes]
```

## Changes

- Add `GET` and `POST /api/experimental/ai/model-prices`, gated behind
the AI Bridge entitlement and the existing `ai_model_price` RBAC
resource.
- Add a `GetAIModelPrices` query with optional `provider` and `model`
filters applied in SQL.
- Validate the whole request before writing anything, so one bad entry
cannot leave the table half updated, and report every problem at once.
- Reject prices for models the embedded price book already covers,
through a new `prices.IsDefaultPriced`.
- Add the `coder exp ai-model-prices` command with `list` and `update`.
`update` accepts a JSON document or the single-model flags and prints a
plan, asking to confirm unless the document is piped in or `--yes` is
passed.
- Consolidate the supported provider list into
`coderd/aibridge/prices/providers` so the price generator and the server
share one definition.
- Add `codersdk` types and client methods for both endpoints, and bound
the request body at 1 MiB.
- Document the command in the AI Gateway cost controls page.

Closes
https://linear.app/codercom/issue/AIGOV-567/experimental-cli-command-to-set-prices-for-unpriced-ai-models

> [!NOTE]
> Initially generated by Claude Opus 5, modified and reviewed by
@ssncferreira
2026-08-13 15:00:36 +01:00
Danielle Maywood abe9c79605 feat(site/src/pages/AgentsPage): render list_subagent_models tool results (#28116) 2026-08-13 13:04:54 +01:00
dependabot[bot] b2c70590db chore: bump the vite group across 1 directory with 2 updates (#28108)
Bumps the vite group with 2 updates in the /site directory:
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react)
and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).

Updates `@vitejs/plugin-react` from 6.0.4 to 6.0.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/releases">@​vitejs/plugin-react's
releases</a>.</em></p>
<blockquote>
<h2>plugin-react@6.0.5</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@​vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.0.5 (2026-07-30)</h2>
<h3>Fixed the react compiler preset filter to be linear (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1353">#1353</a>)</h3>
<p>The improved filter in v6.0.3 was non-linear and caused a performance
regression (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/issues/1349">#1349</a>).
The filter was changed to be linear to avoid that.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/68c0cb8796ce18bd049c3d05c5210eaf0617eac0"><code>68c0cb8</code></a>
release: plugin-react@6.0.5 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1362">#1362</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/555cdbc126506317b05404481374406771a41e70"><code>555cdbc</code></a>
fix(react): make the react compiler preset filter linear (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1353">#1353</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/a00a9f8240d5a7bb4062ee2a5bac68ea4f0defa6"><code>a00a9f8</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1327">#1327</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.5/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.1.5 to 8.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>create-vite@8.2.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/create-vite@8.2.0/packages/create-vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>plugin-legacy@8.2.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/plugin-legacy@8.2.0/packages/plugin-legacy/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.2.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.2.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.2.0-beta.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.2.0-beta.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/vitejs/vite/compare/v8.2.0-beta.0...v8.2.0">8.2.0</a>
(2026-07-30)</h2>
<h3>Features</h3>
<ul>
<li>add <code>input</code> to <code>server.fs.allow</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/23035">#23035</a>)
(<a
href="https://github.com/vitejs/vite/commit/95a3cdab83e1125b03d2e8dd942fb6b64209e5fa">95a3cda</a>)</li>
<li><strong>bundled-dev:</strong> reload once after rebuild instead of
via the fallback page (<a
href="https://redirect.github.com/vitejs/vite/issues/23106">#23106</a>)
(<a
href="https://github.com/vitejs/vite/commit/b24381d741941b9ce2b1c07db62cc5f4d7bad981">b24381d</a>)</li>
<li><strong>bundled-dev:</strong> support worker file update accepted by
HMR (<a
href="https://redirect.github.com/vitejs/vite/issues/23068">#23068</a>)
(<a
href="https://github.com/vitejs/vite/commit/0d04351fdc12258c75b9f1cda5780fdb836ed0ef">0d04351</a>)</li>
<li><strong>config:</strong> include column in config incompatibility
location (<a
href="https://redirect.github.com/vitejs/vite/issues/23064">#23064</a>)
(<a
href="https://github.com/vitejs/vite/commit/8a245726944ed29225920d49be77c33c6e03afc8">8a24572</a>)</li>
<li><strong>dev:</strong> resolve interface name for explicit host in
network URLs (<a
href="https://redirect.github.com/vitejs/vite/issues/22965">#22965</a>)
(<a
href="https://github.com/vitejs/vite/commit/3ac77d9dd742968961af38a5a91ed6b061ceda7d">3ac77d9</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>bundledDev:</strong> print build errors to the terminal when
an HMR update fails (<a
href="https://redirect.github.com/vitejs/vite/issues/23024">#23024</a>)
(<a
href="https://github.com/vitejs/vite/commit/41c465896e8b11b1eb9c5fbdafbdcc528e189a2c">41c4658</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/23069">#23069</a>)
(<a
href="https://github.com/vitejs/vite/commit/4c07b74416f859d7e8bdace13409ef2d080edf76">4c07b74</a>)</li>
<li><strong>hmr:</strong> preserve environment snapshot during server
restart (<a
href="https://redirect.github.com/vitejs/vite/issues/22992">#22992</a>)
(<a
href="https://github.com/vitejs/vite/commit/b1186c36d06bb94941c58e8272fc4acb8512c93b">b1186c3</a>)</li>
<li><strong>importAnalysis:</strong> interop imports injected into
optimized dep files by plugins (<a
href="https://redirect.github.com/vitejs/vite/issues/23029">#23029</a>)
(<a
href="https://github.com/vitejs/vite/commit/8c2a87d41fb24536e59643351758084cde4d0dd7">8c2a87d</a>)</li>
<li><strong>module-runner:</strong> keep stack trace interception
working when <code>Object.prototype</code> is frozen (<a
href="https://redirect.github.com/vitejs/vite/issues/23073">#23073</a>)
(<a
href="https://github.com/vitejs/vite/commit/599c5b02a8b6879b05ede988020f1331e877aaea">599c5b0</a>)</li>
<li><strong>server:</strong> strip base in indexHtml module graph lookup
(<a
href="https://redirect.github.com/vitejs/vite/issues/22932">#22932</a>)
(<a
href="https://github.com/vitejs/vite/commit/fa005d19af5d847931c6dbefc63841c137383e6c">fa005d1</a>)</li>
<li>support resolving top-level input option with plugins (<a
href="https://redirect.github.com/vitejs/vite/issues/23101">#23101</a>)
(<a
href="https://github.com/vitejs/vite/commit/41df81a6a4c3eef08f7a9a8ac9530cd136c0eafa">41df81a</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li><strong>config:</strong> correct cacheDir default fallback
description (<a
href="https://redirect.github.com/vitejs/vite/issues/23060">#23060</a>)
(<a
href="https://github.com/vitejs/vite/commit/aafa103af5d71fb59d7c3dd617d0cbef3b222f1f">aafa103</a>)</li>
</ul>
<h3>Tests</h3>
<ul>
<li>config CJS module vars in ESM case (<a
href="https://redirect.github.com/vitejs/vite/issues/23010">#23010</a>)
(<a
href="https://github.com/vitejs/vite/commit/d8cd38830251b95fd7dddcd0eee0ce94cc61c2f4">d8cd388</a>)</li>
</ul>
<h2><a
href="https://github.com/vitejs/vite/compare/v8.1.5...v8.2.0-beta.0">8.2.0-beta.0</a>
(2026-07-22)</h2>
<h3>Features</h3>
<ul>
<li>add <code>input</code> option (<a
href="https://redirect.github.com/vitejs/vite/issues/22642">#22642</a>)
(<a
href="https://github.com/vitejs/vite/commit/9beae37d7221b25463a011feb40b0303ca328d87">9beae37</a>)</li>
<li><strong>config:</strong> warn features incompatible with native
loader in bundle loader (<a
href="https://redirect.github.com/vitejs/vite/issues/22850">#22850</a>)
(<a
href="https://github.com/vitejs/vite/commit/05302b07267f6b4f9dbeac5b1d73fcc3dc06d730">05302b0</a>)</li>
<li><strong>css:</strong> export PostCSS config type for type-safe
configs (<a
href="https://redirect.github.com/vitejs/vite/issues/22792">#22792</a>)
(<a
href="https://github.com/vitejs/vite/commit/302c755a8125b9a26214e3b413922b5513e41981">302c755</a>)</li>
<li><strong>dev:</strong> label network URLs with their interface name
(<a
href="https://redirect.github.com/vitejs/vite/issues/22830">#22830</a>)
(<a
href="https://github.com/vitejs/vite/commit/78accc42a5b8887d9df624f7d4a934d3ead677d1">78accc4</a>)</li>
<li><strong>optimizer:</strong> support aube lockfile (<a
href="https://redirect.github.com/vitejs/vite/issues/22813">#22813</a>)
(<a
href="https://github.com/vitejs/vite/commit/6319827116c5be2a19c1b91c84ba3d38ad26a41c">6319827</a>)</li>
<li><strong>optimizer:</strong> support nub lockfile (<a
href="https://redirect.github.com/vitejs/vite/issues/22891">#22891</a>)
(<a
href="https://github.com/vitejs/vite/commit/65d3604f6fdbfcf6e86244d7fe3c1ca86acae701">65d3604</a>)</li>
<li>update rolldown-related dependencies and use client-side HMR in
bundled-dev (<a
href="https://redirect.github.com/vitejs/vite/issues/22961">#22961</a>)
(<a
href="https://github.com/vitejs/vite/commit/960e9efbc1372000caac46cc2f123cef4824e2bb">960e9ef</a>)</li>
<li><strong>wasm:</strong> expand test suite, unwrap WebAssembly.Global
and enable js-string builtins (<a
href="https://redirect.github.com/vitejs/vite/issues/22674">#22674</a>)
(<a
href="https://github.com/vitejs/vite/commit/9e79b51579457a9af4fa623b68a0bfabbf38010b">9e79b51</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>build:</strong> map CSS chunks in chunk import maps (fix <a
href="https://redirect.github.com/vitejs/vite/issues/22946">#22946</a>)
(<a
href="https://redirect.github.com/vitejs/vite/issues/22947">#22947</a>)
(<a
href="https://github.com/vitejs/vite/commit/e16ff3a1199293ac9cdfa6132c08fdea162215f3">e16ff3a</a>)</li>
<li><strong>config:</strong> exclude virtual modules from native config
compat check (<a
href="https://redirect.github.com/vitejs/vite/issues/22979">#22979</a>)
(<a
href="https://github.com/vitejs/vite/commit/2ced1fe4e4e480ed78cb7aa5c78319e57bfa7783">2ced1fe</a>)</li>
<li><strong>css:</strong> rewrite urls in OnceExit-injected content (<a
href="https://redirect.github.com/vitejs/vite/issues/22983">#22983</a>)
(<a
href="https://github.com/vitejs/vite/commit/abb793e18c92592c21fbb8e1f3fc450b5839f04f">abb793e</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22985">#22985</a>)
(<a
href="https://github.com/vitejs/vite/commit/04f345b37064cd0bba6447eb5c32be5c22162f3d">04f345b</a>)</li>
<li><strong>deps:</strong> update dependency magic-string to v1 (<a
href="https://redirect.github.com/vitejs/vite/issues/22998">#22998</a>)
(<a
href="https://github.com/vitejs/vite/commit/c60b4d7cdb85b7d4f78671cdcfb863e5f8b66bb7">c60b4d7</a>)</li>
<li><strong>hmr:</strong> remove hot data after prune (<a
href="https://redirect.github.com/vitejs/vite/issues/23002">#23002</a>)
(<a
href="https://github.com/vitejs/vite/commit/be9631658f5191ee5c5665e780239d42a330280a">be96316</a>)</li>
<li>resolve root to real path (<a
href="https://redirect.github.com/vitejs/vite/issues/22832">#22832</a>)
(<a
href="https://github.com/vitejs/vite/commit/55bba7bbd9de40d031360e4408fe91bff5b29ec9">55bba7b</a>)</li>
</ul>
<h3>Performance Improvements</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/24a611f1c83a976d32262628d42f683609746635"><code>24a611f</code></a>
release: v7.2.4</li>
<li><a
href="https://github.com/vitejs/vite/commit/2d66b7b14aa6dfd62f3d6a59ee8382ed5ca6fd32"><code>2d66b7b</code></a>
fix: revert &quot;perf(deps): replace debug with obug (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21107">#21107</a>)&quot;</li>
<li><a
href="https://github.com/vitejs/vite/commit/a668014dba377c2b82a32d8124f1761e9ea74f82"><code>a668014</code></a>
release: v7.2.3</li>
<li><a
href="https://github.com/vitejs/vite/commit/acfe939e1f7c303c34b0b39b883cc302da767fa2"><code>acfe939</code></a>
perf(deps): replace debug with obug (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21107">#21107</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/4f8171eb3046bd70c83964689897dab4c6b58bc0"><code>4f8171e</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21128">#21128</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/50297208452241061cb44d09a4bbdf77a11ac01e"><code>5029720</code></a>
chore(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21127">#21127</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/5909efd8fbfd1bf1eab65427aea0613124b2797a"><code>5909efd</code></a>
fix: allow multiple <code>bindCLIShortcuts</code> calls with shortcut
merging (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21103">#21103</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/39a0a15fd24ed37257c48b795097a3794e54d255"><code>39a0a15</code></a>
chore(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21095">#21095</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/6a34ac3422686e7cf7cc9a25d299cb8e5a8d92a0"><code>6a34ac3</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21096">#21096</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/02ceaec45e17bef19159188a28d9196fed1761be"><code>02ceaec</code></a>
chore(deps): update dependency <code>@​rollup/plugin-commonjs</code> to
v29 (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/21099">#21099</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/create-vite@8.2.0/packages/vite">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 11:16:26 +00:00
dependabot[bot] 314897631d chore: bump @types/lodash from 4.17.24 to 4.17.25 in /site (#28114)
Bumps
[@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash)
from 4.17.24 to 4.17.25.
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 11:08:47 +00:00
dependabot[bot] f792ba45fd chore: bump postcss from 8.5.18 to 8.5.26 in /site (#28113)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.18 to
8.5.26.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/releases">postcss's
releases</a>.</em></p>
<blockquote>
<h2>8.5.26</h2>
<ul>
<li>Fixed <code>list.split()</code> regression (by <a
href="https://github.com/lazerg"><code>@​lazerg</code></a>).</li>
<li>Track symlinks in path protection in source map loading (by <a
href="https://github.com/drengir1"><code>@​drengir1</code></a>).</li>
</ul>
<h2>8.5.25</h2>
<ul>
<li>Fixed 8.5.17 visitor regression.</li>
<li>Fixed <code>list.split()</code> for non-string values (by <a
href="https://github.com/amir-rezaei"><code>@​amir-rezaei</code></a>).</li>
</ul>
<h2>8.5.24</h2>
<ul>
<li>Preserve the BOM after the processing (by <a
href="https://github.com/hdimer"><code>@​hdimer</code></a>).</li>
</ul>
<h2>8.5.23</h2>
<ul>
<li>Do not load source map without <code>opts.from</code> for security
reasons.</li>
</ul>
<h2>8.5.22</h2>
<ul>
<li>Fixed custom property losing semicolon before a comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.21</h2>
<ul>
<li>Fixed childless at-rule losing semicolon before comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed docs (by <a
href="https://github.com/isker"><code>@​isker</code></a>).</li>
</ul>
<h2>8.5.20</h2>
<ul>
<li>Fixed missing space if <code>AtRule#params</code> is set after (by
<a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed mixing AST error on warnings (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.19</h2>
<ul>
<li>Fixed cleaning <code>before</code> for new nodes inserted to
<code>Root</code> (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/postcss/postcss/blob/main/CHANGELOG.md">postcss's
changelog</a>.</em></p>
<blockquote>
<h2>8.5.26</h2>
<ul>
<li>Fixed <code>list.split()</code> regression (by <a
href="https://github.com/lazerg"><code>@​lazerg</code></a>).</li>
<li>Track symlinks in path protection in source map loading (by <a
href="https://github.com/drengir1"><code>@​drengir1</code></a>).</li>
</ul>
<h2>8.5.25</h2>
<ul>
<li>Fixed 8.5.17 visitor regression.</li>
<li>Fixed <code>list.split()</code> for non-string values (by <a
href="https://github.com/amir-rezaei"><code>@​amir-rezaei</code></a>).</li>
</ul>
<h2>8.5.24</h2>
<ul>
<li>Preserve the BOM after the processing (by <a
href="https://github.com/hdimer"><code>@​hdimer</code></a>).</li>
</ul>
<h2>8.5.23</h2>
<ul>
<li>Do not load source map without <code>opts.from</code> for security
reasons.</li>
</ul>
<h2>8.5.22</h2>
<ul>
<li>Fixed custom property losing semicolon before a comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
</ul>
<h2>8.5.21</h2>
<ul>
<li>Fixed childless at-rule losing semicolon before comment (by <a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed docs (by <a
href="https://github.com/isker"><code>@​isker</code></a>).</li>
</ul>
<h2>8.5.20</h2>
<ul>
<li>Fixed missing space if <code>AtRule#params</code> is set after (by
<a
href="https://github.com/sarathfrancis90"><code>@​sarathfrancis90</code></a>).</li>
<li>Fixed mixing AST error on warnings (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
<h2>8.5.19</h2>
<ul>
<li>Fixed cleaning <code>before</code> for new nodes inserted to
<code>Root</code> (by <a
href="https://github.com/MahinAnowar"><code>@​MahinAnowar</code></a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/postcss/postcss/commit/07b25773f38f77919f2af02ae3e8896b0deb5988"><code>07b2577</code></a>
Release 8.5.26 version</li>
<li><a
href="https://github.com/postcss/postcss/commit/47de6b9d7c55674cb326c5de7a734a740916defc"><code>47de6b9</code></a>
Update CI</li>
<li><a
href="https://github.com/postcss/postcss/commit/1493a83db7830912316512f55ab6064e7b7dd68e"><code>1493a83</code></a>
Fix Rule#selectors losing the empty selector (<a
href="https://redirect.github.com/postcss/postcss/issues/2129">#2129</a>)</li>
<li><a
href="https://github.com/postcss/postcss/commit/180db166e250d20e6761b224ae8d8134c9ba3e40"><code>180db16</code></a>
Typo</li>
<li><a
href="https://github.com/postcss/postcss/commit/29e9e00f132c96e46e1de295b816fe88a05354e7"><code>29e9e00</code></a>
Resolve symlinks before the previous-source-map containment check (<a
href="https://redirect.github.com/postcss/postcss/issues/2125">#2125</a>)</li>
<li><a
href="https://github.com/postcss/postcss/commit/3ba8f84703a884329b58abea579c3615684e0b7e"><code>3ba8f84</code></a>
Update dependencies</li>
<li><a
href="https://github.com/postcss/postcss/commit/87e72f671fd0d401c52822b5226c656632d92ec0"><code>87e72f6</code></a>
Update lock file</li>
<li><a
href="https://github.com/postcss/postcss/commit/caaeeb907e4a816c44a23b00b151882bd02325a1"><code>caaeeb9</code></a>
Upgrade nanoid to fix infinite loop on zero size (<a
href="https://redirect.github.com/postcss/postcss/issues/2124">#2124</a>)</li>
<li><a
href="https://github.com/postcss/postcss/commit/3609b6f4296952d0b5b9ddae42c8d73ee460c041"><code>3609b6f</code></a>
Explain how to type plugin options</li>
<li><a
href="https://github.com/postcss/postcss/commit/fbad419cbd01cd7a9a1a46413447f2cd9b3fce4a"><code>fbad419</code></a>
docs: show ESM and TypeScript plugin declaration (<a
href="https://redirect.github.com/postcss/postcss/issues/2118">#2118</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/postcss/postcss/compare/8.5.18...8.5.26">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 11:06:12 +00:00
dependabot[bot] a742b53b26 chore: bump motion from 12.42.2 to 12.43.0 in /site (#28111)
Bumps [motion](https://github.com/motiondivision/motion) from 12.42.2 to
12.43.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/motiondivision/motion/blob/main/CHANGELOG.md">motion's
changelog</a>.</em></p>
<blockquote>
<h2>[12.43.0] 2026-07-27</h2>
<h3>Added</h3>
<ul>
<li>Hardware acceleration for <code>backgroundColor</code> in supported
browsers.</li>
<li>Hardware acceleration for SVG elements.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li><code>AnimatePresence</code>: Exiting children no longer interleave
with entering children, which could reorder and remount children present
in both renders.</li>
<li><code>motion</code>: Throw error when passing a custom
<code>motion</code> component an incorrect <code>ref</code> type.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/motiondivision/motion/commit/a4ef40a5dd378205a41dbb19e7fad04e3280607f"><code>a4ef40a</code></a>
v12.43.0</li>
<li><a
href="https://github.com/motiondivision/motion/commit/14f2d286d1b0805ca8a34b41f9c4122a36e215eb"><code>14f2d28</code></a>
adding svg acceleration</li>
<li><a
href="https://github.com/motiondivision/motion/commit/1f5a27b828d42574ff3dfffa29f77da613d84eb2"><code>1f5a27b</code></a>
Fixing merge</li>
<li><a
href="https://github.com/motiondivision/motion/commit/79f03532429c6abee2de5161e3ca1594aa2d61f0"><code>79f0353</code></a>
Updating changelog</li>
<li><a
href="https://github.com/motiondivision/motion/commit/57f179b1beaec64da990ca914c18697f87265b4f"><code>57f179b</code></a>
Updating changelog</li>
<li><a
href="https://github.com/motiondivision/motion/commit/695cb3954d4df55ca0794bc95f084b377e4f5f4f"><code>695cb39</code></a>
Merge pull request <a
href="https://redirect.github.com/motiondivision/motion/issues/3755">#3755</a>
from motiondivision/fix-issue-2777</li>
<li><a
href="https://github.com/motiondivision/motion/commit/33a1820f6c35e9b206eca277e059415b07ddafde"><code>33a1820</code></a>
Drop the production fallback for non-DOM refs</li>
<li><a
href="https://github.com/motiondivision/motion/commit/ebe35f223ddda0806af8d8335e7f053115d67d4b"><code>ebe35f2</code></a>
Throw an actionable invariant for non-DOM custom component refs</li>
<li><a
href="https://github.com/motiondivision/motion/commit/a6ed0946a338256f660560500861b09c2b8a20d2"><code>a6ed094</code></a>
Merge pull request <a
href="https://redirect.github.com/motiondivision/motion/issues/3754">#3754</a>
from motiondivision/fix-3745-popchild-ref-warning</li>
<li><a
href="https://github.com/motiondivision/motion/commit/9f251f3377766a6bf97a93c1634c4e51a7408ccf"><code>9f251f3</code></a>
Merge pull request <a
href="https://redirect.github.com/motiondivision/motion/issues/3763">#3763</a>
from motiondivision/advisor/003-color-waapi</li>
<li>Additional commits viewable in <a
href="https://github.com/motiondivision/motion/compare/v12.42.2...v12.43.0">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 11:05:57 +00:00
dependabot[bot] 089c08e10c chore: bump react-router from 7.18.0 to 7.18.2 in /site (#28115)
Bumps
[react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router)
from 7.18.0 to 7.18.2.
<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.18.2</h2>
<p>See the changelog for release notes: <a
href="https://github.com/remix-run/react-router/blob/v7/CHANGELOG.md#v7182">https://github.com/remix-run/react-router/blob/v7/CHANGELOG.md#v7182</a></p>
<h2>v7.18.1</h2>
<p>See the changelog for release notes: <a
href="https://github.com/remix-run/react-router/blob/v7/CHANGELOG.md#v7181">https://github.com/remix-run/react-router/blob/v7/CHANGELOG.md#v7181</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/remix-run/react-router/blob/react-router@7.18.2/packages/react-router/CHANGELOG.md">react-router's
changelog</a>.</em></p>
<blockquote>
<h2>v7.18.2</h2>
<h3>Patch Changes</h3>
<ul>
<li>Harden RSC CSRF codepaths. (<a
href="https://redirect.github.com/remix-run/react-router/pull/15353">#15353</a>)</li>
</ul>
<h2>v7.18.1</h2>
<h3>Patch Changes</h3>
<ul>
<li><em>No changes</em></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/remix-run/react-router/commit/69a653ee6ab1ac95b13c917ec56c5f3dc17ca9c1"><code>69a653e</code></a>
Release v7.18.2 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15354">#15354</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/8ebd5df9932854547963e3255c8454e62430e05d"><code>8ebd5df</code></a>
Harden RSC CSRF codepaths (backport of <a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15311">#15311</a>)
(<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15353">#15353</a>)</li>
<li><a
href="https://github.com/remix-run/react-router/commit/afdf85d3c15448a41017514caca2aca038d3e9ca"><code>afdf85d</code></a>
Release v7.18.1 (<a
href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15253">#15253</a>)</li>
<li>See full diff in <a
href="https://github.com/remix-run/react-router/commits/react-router@7.18.2/packages/react-router">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=react-router&package-manager=npm_and_yarn&previous-version=7.18.0&new-version=7.18.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 show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 11:04:31 +00:00
dependabot[bot] 15ee136921 chore: bump react-infinite-scroll-component from 7.1.0 to 7.2.1 in /site (#28112)
Bumps
[react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component)
from 7.1.0 to 7.2.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/releases">react-infinite-scroll-component's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.1 - Accessibility props</h2>
<h2>What's new</h2>
<h3>Accessibility props</h3>
<p>You can now pass <code>role</code>, <code>aria-label</code>,
<code>aria-labelledby</code>, <code>tabIndex</code>, <code>id</code>,
and any <code>aria-*</code> attribute directly to the scroll
container:</p>
<pre lang="tsx"><code>&lt;InfiniteScroll
  role=&quot;list&quot;
  aria-label=&quot;Search results&quot;
  dataLength={items.length}
  next={fetchMore}
  hasMore={hasMore}
  loader={&lt;p&gt;Loading...&lt;/p&gt;}
&gt;
  {items.map(item =&gt; (
&lt;div role=&quot;listitem&quot;
key={item.id}&gt;{item.name}&lt;/div&gt;
  ))}
&lt;/InfiniteScroll&gt;
</code></pre>
<p>Closes <a
href="https://redirect.github.com/ankeetmaini/react-infinite-scroll-component/issues/411">#411</a>.
Thanks to <a
href="https://github.com/sayedrisat"><code>@​sayedrisat</code></a> for
the contribution!</p>
<h2>Commits</h2>
<ul>
<li>feat: add accessibility props to scroll container (<a
href="https://redirect.github.com/ankeetmaini/react-infinite-scroll-component/issues/432">#432</a>)</li>
<li>docs: expand accessibility props table and add usage examples (<a
href="https://redirect.github.com/ankeetmaini/react-infinite-scroll-component/issues/433">#433</a>)</li>
</ul>
<h2>v7.2.0 - useInfiniteScroll hook</h2>
<h2>What's new</h2>
<h3><code>useInfiniteScroll</code> hook</h3>
<p>A new named export for building fully custom infinite scroll UIs. The
hook manages the <code>IntersectionObserver</code> lifecycle and exposes
<code>sentinelRef</code> and <code>isLoading</code> — your markup, your
styles, your loader.</p>
<pre lang="tsx"><code>import { useInfiniteScroll } from
'react-infinite-scroll-component';
<p>const { sentinelRef, isLoading } = useInfiniteScroll({<br />
next: fetchMore,<br />
hasMore,<br />
dataLength: items.length,<br />
});<br />
</code></pre></p>
<p>Attach <code>sentinelRef</code> to any element at the end of your
list. <code>isLoading</code> is <code>true</code> from when
<code>next()</code> fires until <code>dataLength</code> changes.</p>
<p>Accepts the same <code>hasMore</code>, <code>dataLength</code>,
<code>next</code>, <code>scrollThreshold</code>,
<code>scrollableTarget</code>, and <code>inverse</code> props as the
<code>InfiniteScroll</code> component.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/8f5ee8c782e9542009c53d3cf09a4e548c4660d5"><code>8f5ee8c</code></a>
chore: bump version to 7.2.1</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/4b957d00b451d6cbd4a99300b8da240a4d1e8d3e"><code>4b957d0</code></a>
docs: add sayedrisat to contributors list</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/b7a3600aed44d039b8e2a407cd1441e807dbb879"><code>b7a3600</code></a>
docs: add accessibility props to table and usage examples</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/dc9f7f4da80629ee8f4efd0e5fc27001a0ce0349"><code>dc9f7f4</code></a>
Scope container props to accessibility attributes</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/0feacda0e92e90bd898373127af289e73addb936"><code>0feacda</code></a>
Add accessibility props to scroll container</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/92b3249f361e97323dc9c0ffde603fb91823196c"><code>92b3249</code></a>
chore: bump version to 7.2.0</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/d896cc9f166e6c2b57effcfd86d2d32d0d67a383"><code>d896cc9</code></a>
fix: update stories.tsx import to renamed ScrollableTop</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/a3102a644304ab1927bbee2044417cb875a8f038"><code>a3102a6</code></a>
docs: fill empty defaults with dash, expand all prop descriptions</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/d93280928ef51481c5d1ee6bdac75cb64f38fbe7"><code>d932809</code></a>
docs: overhaul README and improve package.json metadata</li>
<li><a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/commit/b53588b1cadfeaef6aec9a70266421d83d0d2ae9"><code>b53588b</code></a>
feat: add AGENTS.md and llms.txt for AI discoverability</li>
<li>Additional commits viewable in <a
href="https://github.com/ankeetmaini/react-infinite-scroll-component/compare/v7.1.0...v7.2.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=react-infinite-scroll-component&package-manager=npm_and_yarn&previous-version=7.1.0&new-version=7.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 10:59:58 +00:00
dependabot[bot] 96553f8105 chore: bump the react group across 1 directory with 2 updates (#28107)
[//]: # (dependabot-start)
⚠️  **Dependabot is rebasing this PR** ⚠️ 

Rebasing might not happen immediately, so don't worry if this takes some
time.

Note: if you make any changes to this PR yourself, they will take
precedence over the rebase.

---

[//]: # (dependabot-end)

Bumps the react group with 2 updates in the /site directory:
[@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react)
and
[@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).

Updates `@types/react` from 19.2.17 to 19.2.18
<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 `@types/react-dom` from 19.2.3 to 19.2.4
<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 />


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

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

---

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

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


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-13 10:57:26 +00:00
Michael Suchacz d509e1e6a0 fix(site): include owner context in Agents org picker permission check (#28076)
Fixes the Agents org picker and workspace attach menu for users whose
only chat grant comes from the member-scoped "Coder Agents User"
(`agents-access`) org role (PRODUCT-552).

## Problem

The per-org authcheck behind the org picker checked `chat:create` with
only `organization_id`. The `agents-access` role grants chat permissions
at org-member scope, which requires the checked object to be owned by
the caller (`policy.rego` `org_member` requires a non-empty owner
matching the subject). With no `owner_id`, every org check returned
`false`, so:

- the org picker never rendered (`permittedOrgs.length > 1` gate),
- the form stayed pinned to the default org,
- the workspace attach menu, filtered to that org, showed "No workspaces
found" even though the user had workspaces in another org.

The page-level `createChat` check already includes `owner_id: "me"`,
which is why the same user could load the page and create chats via the
API.

## Fix

Pass `owner_id: "me"` in the `permittedOrganizations` seed check in
`AgentCreateForm`, matching the page-level check's semantics. The
`permittedOrganizations` helper spreads the check object through, so
each per-org check now carries owner context and the backend substitutes
the caller's user ID.

The other `permittedOrganizations` callsites
(`organization_member:create`, `template:create`) check org-scoped admin
permissions and correctly omit `owner_id`.

Adds a regression story whose `checkAuthorization` mock only allows
checks carrying `owner_id: "me"` (mirroring the RBAC member-scope
behavior); it fails without the fix and passes with it (red-green
verified).

## Validation

- Red-green verified regression story: fails without the fix (picker not
found), passes with it; all 31 stories in the file pass.
- `pnpm -C site check` and `pnpm -C site lint:types` clean.
- Remote dogfood UAT (dev.coder.com chat
[97be7f39](https://dev.coder.com/agents/97be7f39-4688-45ee-be3d-24bc4f6f8046)):
PASS on all acceptance criteria at this exact commit. Reproduced the bug
scenario end to end (two orgs, non-admin user with only the "Coder
Agents User" role in both, workspace only in the second org): the org
picker renders, the second org's workspaces appear in the attach menu,
and chat creation succeeds with a real model. Single-org and admin
behaviors unchanged. Authcheck probe documents the backend semantics:
`chat:create` with `owner_id: "me"` returns true, without it returns
false.

> Mux acted on Mike's behalf for this PR.
2026-08-13 11:19:38 +02:00
Michael Suchacz 1458d27d78 fix: allow manual chat compaction from the error state (#28022)
A chat that fails generation with a context overflow (for example `Input
length 262625 exceeds the maximum allowed input length of 262112
tokens`) is stuck in a catch-22: `POST /chats/{id}/compact` returns 409
because the `RequestCompaction` transition is only allowed from the
waiting state, and the only other way out of the error state is sending
or editing a message, which re-runs generation with the same oversized
prompt and fails again. Compaction is exactly the recovery a
context-overflowed chat needs, and it is unreachable exactly when it is
needed.

Three semantic changes:

- Allow `RequestCompaction` from the error states: `E0 -> R0` and `E1 ->
R1` (queued messages are preserved and processed after the compaction
turn).
- Clear `last_error` in `Tx.RequestCompaction`, matching the
architecture rule that transitions leaving `E0`/`E1` clear the stored
error. Without this a successful compaction would land in waiting with a
stale persisted error.
- Grant the compaction turn a fresh history epoch: a
`grant_history_epoch` flag on `UpdateChatExecutionState` sets
`history_version = snapshot_version`, resets `generation_attempt`, and
clears `retry_state` in the same atomic update that clears `last_error`
(mirroring the `chat_messages` trigger postcondition). The transition
inserts no history, so without this the turn inherits the failed turn's
spent retry budget, and resetting the counter alone could collide with
message part episode keys still retained on the erroring replica.

No frontend change is required: the chat input is already enabled in the
error state and `/compact` submission already handles both the success
and 409 paths. Also updates ARCHITECTURE.md (transition matrix,
endpoint, and manual compaction sections), the endpoint's swagger
description, and SDK comments.

> Mux created this PR on Mike's behalf.

<!-- mux-attribution: model=claude-sonnet-4-6 thinking=high -->
2026-08-12 20:38:57 +02:00
TJ b145142404 fix(site): add aria-label to icon-only Back navigation links (#26222)
## Summary

Two icon-only "Back" navigation links in the topbars have no accessible
name. The visible tooltip text is wired via Radix's `aria-describedby`,
which provides a *description*, not an accessible **name**, so screen
readers announce them as just "link" with no purpose.

This adds an `aria-label` to each link matching the visible tooltip
text, following the existing `aria-label` convention already used in
these same files (e.g. `aria-label="Create File"`, `aria-label="Daily
usage"`).

## WCAG 2.1 criteria addressed

- **SC 4.1.2 Name, Role, Value** (Level A)
- **SC 2.4.4 Link Purpose (In Context)** (Level A)

## Changes

| File | Element | Added |
|---|---|---|
| `site/src/pages/WorkspacePage/WorkspaceTopbar.tsx` |
Back-to-workspaces chevron link | `aria-label="Back to workspaces"` |
| `site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx` |
Back-to-template chevron link | `aria-label="Back to the template"` |

No visual change. No behavior change for sighted users. `aria-label` is
safe here because the elements have no visible text content (only an
icon), so it is not overriding a visible name.

<details>
<summary>Why not rely on the existing Tooltip?</summary>

Radix UI's `Tooltip` wires `aria-describedby` from the trigger to the
tooltip content. `aria-describedby` provides an *accessible
description*, not an *accessible name*. WCAG 4.1.2 requires interactive
controls to have a programmatically determinable name, and screen
readers do not consistently announce descriptions, especially when no
name is present. Adding `aria-label` gives the link a stable,
programmatic name that exactly matches the visible tooltip text.

</details>

---

_Created by Coder Agents on behalf of @tracyjohnsonux._
2026-08-12 17:23:37 +00:00
Danielle Maywood 5a33b669b4 feat: redesign the advisor tool row (#28069) 2026-08-12 15:35:31 +01:00
Danielle Maywood c424a76a12 feat: wire chat search box to full-text search (#27973) 2026-08-12 15:04:01 +01:00
Seth Shelnutt 6765731ea9 feat(site/src/pages/AgentsPage): add download and export for personal skills (#28032)
## Summary

Adds a way to get personal skills back out of Coder Agents as files, so
sharing a skill no longer means pasting `SKILL.md` by hand.

- **Per-skill Download**: a `Download` action on each row of the
*Personal
  skills* settings page saves that skill's `SKILL.md` as `<name>.md`.
- **Export all**: a header button zips every personal skill (each as
  `<name>/SKILL.md`) and downloads `personal-skills.zip`.

Scope is **personal skills only** (workspace/filesystem skills are
read-only
in chat and out of scope). No backend changes: the single-skill content
endpoint (`GET /api/experimental/users/{user}/skills/{skillName}`)
already
returns full content, so the view fetches on demand and downloads with
`file-saver`, zipping with `jszip` (both existing deps, matching
`DownloadLogsDialog`).

## Changes

- `AgentSettingsPersonalSkillsPageView.tsx`: `Download` per-row button
(with
per-row spinner) and an `Export all` header button (disabled when empty
or
  loading).
- `AgentSettingsPersonalSkillsPage.tsx`: container handlers that fetch
  content via `queryClient.fetchQuery(userSkill(name))` and trigger the
download/zip, with `toast` error handling. Download logic is extracted
to
  module-level helpers to stay React Compiler friendly.
- `AgentSettingsPersonalSkillsPageView.stories.tsx`: interaction stories
  asserting `onDownload`/`onExportAll` fire, plus loading-state stories.

## Testing

- `pnpm check` (biome), `pnpm lint:types` (tsc), React Compiler check,
and
  Storybook interaction tests (22 passed) all pass locally.
- `make pre-commit` passed.

Closes
[CODAGT-918](https://linear.app/codercom/issue/CODAGT-918/add-ability-to-download-and-export-skills-from-coder-agents).

<details>
<summary>Implementation plan</summary>

### Problem

Users can create, edit, and delete personal skills in Agent settings,
but
there is no way to get a skill back out as a file. The only workaround
was to
paste the `SKILL.md` content by hand.

### Decisions (confirmed with requester)

1. Surface: download in the settings UI (Personal skills page).
2. Build both single-skill download and export-all (zip).
3. Personal skills only (workspace/filesystem skills out of scope).

### Approach (frontend-only, additive)

No backend changes: the single-skill content endpoint already exists.
The
view stays presentational and exposes new callbacks; the container
fetches
content and performs the download, mirroring how Edit/Delete already
split
between view and container.

- Per-row Download button, placed before Edit in the actions cell; shows
a
  spinner while its own row is downloading.
- Export all button in the section header, disabled when there are no
skills
  or while loading.
- Container: single download fetches content and `saveAs(<name>.md)`;
export
  all fetches every skill, adds each as `<name>/SKILL.md` to a `JSZip`,
generates a blob, and `saveAs(personal-skills.zip)`. Failures surface
via
  `toast.error`.
- Stories cover the interactions and loading states (stories are the FE
test
  surface).

### Out of scope

- Workspace skills download (filesystem source): different data path,
  read-only in chat, not user-owned data.
- In-chat download button on the `read_skill` tool output: possible
  follow-up, different surface and interaction model.

</details>

---

_Opened by Coder Agents on behalf of @Shelnutt2._
2026-08-12 09:20:30 -04:00
Michael Suchacz ac11ae52d1 fix(site/src/pages/AgentsPage): stop attachment downloads from trapping iOS PWAs (#27853)
On iOS, tapping an attachment download link inside the installed
(standalone) PWA hands the file to QuickLook, which renders on top of
the app with no reliable way back. Users had to force-quit the PWA to
recover.

## Approach

In iOS standalone mode, when the device supports file sharing, the
download click is intercepted and the fetched attachment is handed to
the native share sheet (`navigator.share` with a `File`), where the user
can pick Save to Files or any other target. This is the
platform-intended path for saving files from a PWA; no library covers it
(FileSaver.js is broken in iOS PWAs, and browser-fs-access falls back to
the same broken anchor path).

Everything else keeps native behavior:

- Non-iOS platforms and regular iOS Safari tabs keep the plain `<a
download>` anchor.
- iOS standalone devices without file sharing keep the anchor too.
- Inline `data:` attachments are decoded locally because the production
CSP (`connect-src 'self'`) blocks fetching them.

## Error model

Deliberately small: a share-sheet dismissal (`AbortError`) is silent, an
expired click gesture (`NotAllowedError`, which happens when the fetch
outlasts transient activation) shows a toast whose Save action retries
with a fresh gesture, and any other failure shows a plain error toast.

An earlier revision carried pending-state tracking, abort-signal
threading through unmount, and a blob-URL tab fallback; those guards
were removed on purpose to keep the change proportionate to the defect.

Also hardens chat file uploads slightly: filenames are sanitized before
upload and the file-picker `accept` attribute mirrors the server's
attachment allowlist.

## Testing

- Storybook interaction tests cover the share happy path and
native-anchor behavior; unit tests cover the intercept gate (including
iPadOS detection), failure toasts, retry action, and inline-data decode.
- Validated on an iPhone against a dev deployment: share sheet opens,
Save to Files works, and the app remains usable afterwards.

> Mux implemented this on Mike's behalf.

<!-- mux-attribution: model=claude-sonnet-4-5 thinking=high -->
2026-08-12 08:31:26 +02:00
Jake Howell 726e86cef7 refactor(site): add <Drawer /> and migrate build logs drawer (#28009)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Follow-up to #27798. That PR introduced a shared `Drawer` primitive by
adding [`vaul`](https://github.com/emilkowalski/vaul) as a dependency.
As raised in review, `vaul` is currently unmaintained, and this drawer
is the only place in the UI using that concept.

This PR takes the
[suggested](https://github.com/coder/coder/pull/27798#pullrequestreview-4901095865)
route: a dead-simple, self-owned drawer that covers this one case well,
built directly on Radix UI's `Dialog` (already a dependency via
`radix-ui`) instead of `vaul`. It keeps the same shadcn-style API
(`Drawer`, `DrawerTrigger`, `DrawerContent`, `DrawerHeader`,
`DrawerFooter`, `DrawerTitle`, `DrawerDescription`, `DrawerClose`) so
usage stays familiar, and migrates `CreateTemplatePage`'s
`BuildLogsDrawer` off MUI onto it.

### What changed

- Add `site/src/components/Drawer/Drawer.tsx`: a reusable drawer/sheet
built on `radix-ui` `Dialog`. Supports a `direction` prop
(`top`/`bottom`/`left`/`right`, default `right`) with slide animations
via `tailwindcss-animate`. No new dependencies.
- Migrate `BuildLogsDrawer` from `@mui/material/Drawer` to the new
component. Desktop panel stays at 800px via `min(800px, 100%)` so it
stays within the viewport on mobile.
- Storybook coverage with `play()` functions for both the generic
`Drawer` (open/close, direction) and `BuildLogsDrawer` (close via the X
button and via Escape assert `onClose`), addressing the earlier P1
review note about covering the controlled close path.

### Why Radix instead of vaul

- `radix-ui` `Dialog` is already a dependency and provides
accessibility, focus management, and open/close state.
- No dependency on an unmaintained package for a single-use concept.
- `vaul`'s drag-to-dismiss gesture is not needed for this build-logs use
case.
2026-08-12 13:51:04 +10:00
TJ 5fab238ed1 fix(site/src/pages/AgentsPage): improve git panel color contrast (#28038)
## Summary

Follow-up to #27012 addressing color contrast in the git panel:

- The orange (`text-content-warning`) **Working** label failed color
contrast. The label in the view switcher trigger and dropdown now uses
`text-content-secondary`. The `CircleDotIcon` keeps its original
`text-content-warning` color as a state indicator.
- The **Commit** and **View PR** buttons now use `text-content-primary`
for their text and icons instead of `text-content-secondary`. The
now-redundant `hover:text-content-primary` was dropped.

No behavior changes; class-only updates in `GitPanel.tsx` and
`RemoteDiffPanel.tsx`.

## Testing

- `biome check` and `tsc --noEmit` pass on the touched files.
- Verified visually via Storybook screenshots of the GitPanel stories.

---

> Generated by Coder Agents on behalf of @tracyjohnsonux.
2026-08-11 14:04:15 -07:00
TJ f7f840ac69 feat(site/src/pages/AgentsPage): consolidate git panel tab strip into a view switcher dropdown (#27012)
## What

Replaces the git panel's tab strip (`[PR #4847] [Working coder] [Working
other]`) with a single dropdown "view switcher" that lists the PR (when
present) and each dirty working repo as items.

Also:

- Moves the PR title to a dedicated row below the switcher, truncated
with a hover tooltip for the full title. The row only appears while the
PR view is active.
- Removes the redundant PR-state badge from the RemoteDiffPanel
sub-header (state is now shown as the colored pill on the switcher
trigger).

## Why

The common multi-view states are `PR only`, `Working only`, or `PR + one
Working repo`. The tab strip was fine for one view but crowded the
toolbar the moment two showed up. Collapsing to a single trigger +
optional dropdown keeps the toolbar quiet in the 80% case and the
switcher stays intuitive when there is more than one thing to look at.

## Screens

Storybook coverage:

- `PullRequestAndWorkingChanges` — collapsed switcher shows the PR state
+ `PR #<n>`, PR title below.
- `ViewSwitcherOpen` (new) — dropdown open with PR and both working
repos, then clicks a working entry to verify the view swaps.
- `DraftPullRequest`, `MergedPullRequest`, `ClosedPullRequest` —
trigger's colored pill reflects state (play assertions added).
- `WorkingChangesOnly`, `BranchOnly`, `MultipleRepos`, `EmptyState`,
`GitNotActive`, `GitStatusLoading` — all pass.
- `EverDirtyRepoGoneClean`, `CleanRepoFromStart` — regression coverage
updated to target the new switcher rather than the old `Working` tab
buttons.

<details>
<summary>Decisions and scoping notes</summary>

### Why a switcher and not a PR-only dropdown

Original design showed multiple PRs in the dropdown, but the server
model only tracks **one PR per chat** (`ChatDiffStatus.pr_number` is a
single field). Multi-PR would need a DB / watcher / SDK change out of
scope for a UI polish PR.

After reviewing frequency of the actual multi-view states (`PR only` and
`Working only` dominate; `PR + Working` shows up during review
iteration; 3+ views is rare), we scaled back to make the dropdown a
**view switcher** that spans the existing tab strip's data: PR + working
repos. Ships today, no backend work.

### Behavior notes

- With a single item the trigger renders as a static pill (no chevron,
no dropdown behavior); it becomes an interactive dropdown once there is
more than one item.
- The colored state pill on the trigger uses `text-git-*-bright` /
`text-content-warning` / `text-content-secondary` (text color only; no
background token).
- Dropdown items render as `[icon] primary secondary` where
primary/secondary is `PR #<n> / title` for the remote entry and `Working
/ repo` for local entries.
- Local (Working) entries are visually nested under the remote/PR entry
when one is present; otherwise they render flush-left.
- When the head branch is known but no PR is opened, the trigger reads
`Branch | <head-branch>`.

</details>

---

_Coder Agent generated on behalf of @tracyjohnsonux._
2026-08-11 12:25:06 -07:00
Jeremy Ruppel e9ee83af69 fix(site/src): gate TemplateExampleCard Use template link on builder state (#28035) 2026-08-11 14:30:37 -04:00
Andrew Aquino b721935fc1 chore(site): add generateConnectionSessionId helper function (#27935)
- adds a `generateConnectionSessionId` helper function which reuses our
existing `generateRandomString` logic
- adds tests for `generateConnectionSessionId` in utils/random.test.ts
(utils/random.ts was previously untested)
- renames our existing `generateRandomString` function to be
`generateRandomBase64String`

additional context in
https://github.com/coder/coder/pull/27671#discussion_r3731213459

This PR doesn't change any of our UIs. The new
`generateConnectionSessionId` function is a piece of frontend plumbing
related to DEVEX-663. I originally implemented #27677 so that web
terminal connections to workspaces would be identified by uuids--but
according to the RFC for DEVEX-663, those connection session ids should
be lowercase hexadecimal strings (not uuids).
2026-08-11 09:38:28 -07:00
Atif Ali d7953bd046 fix(coderd): use service account wording in account notifications (#27536) 2026-08-11 13:16:25 +00:00
Michael Suchacz 57f38b5c24 fix: keep chat attachments while a linking chat exists
Fixes https://linear.app/codercom/issue/CODAGT-616/keep-chat-attachments-while-chats-remain-unarchived

Chat attachments could disappear even though the chat was still available. This happened when a message was saved without recording which attachments it used, or when cleanup deleted attachments before an archived chat itself was removed.

Creating a chat, sending or queuing a message, and editing a message now record both the message and which attachments it uses as one operation. If the chat is already at the 50-attachment limit, the chat change fails without being partially saved.

Concurrent attachment writes serialize the 50-file cap per chat. Cleanup locks candidates and checks again for new links before deleting. If a file becomes unavailable after input validation, create, send, and edit return a clear client error and roll back the chat change.

An attachment stays available while any chat that uses it still exists. After an archived chat reaches the end of its retention period and is deleted, an old attachment that no remaining chat uses can be cleaned up. The retention guide and unavailable-attachment UI text document this lifecycle. This change cannot restore attachments that were already deleted.

The database migration adds two indexes so attachment cleanup stays fast as attachments accumulate.

> This PR was authored by Mux (AI) on Mike's behalf.
2026-08-11 13:53:15 +02:00
Danielle Maywood df278ec079 fix: derive diff cache keys from patch content (#27987) 2026-08-11 12:22:13 +01:00
Michael Suchacz 2e5353bde7 feat: add built-in Browser tab for agent-browser (#27910)
Adds a built-in Browser tab to the Agents page right panel, alongside
the built-in Terminal and Desktop tabs, when the chat's bound agent has
an app with the well-known slug `agent-browser`. The tab shows only
while the app is embeddable and its health is `healthy` (or `disabled`,
for templates without a healthcheck), so it appears and disappears live
as the daemon comes up or goes down. The iframe stays mounted across tab
switches to preserve session state.

To avoid duplicates, the generic Add Tab menu and persisted
workspace-app tabs now exclude the `agent-browser` app. Detection uses
the existing `coder_app` slug and healthcheck signals already present in
the workspace data model. The workspace watch handler compares the agent
app fields the chat UI consumes, so health transitions propagate without
re-render churn on every heartbeat.

On the backend, the chat `execute` tool now exports
`AGENT_BROWSER_SESSION=<chat id>` on every process it starts.
agent-browser resolves its default session from that variable, so
browser automation from each chat lands in its own isolated session
(named by the chat id in the embedded dashboard) instead of a shared
default browser.

> Mux created this PR on Mike's behalf.
2026-08-11 12:49:12 +02:00
Thomas Kosiewski 496ed757ed fix: prevent IP leaks via external chat images (#27362) 2026-08-11 11:50:56 +02:00
Jake Howell b3acf7f75a refactor(site): migrate organization settings form off MUI (#27718)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

Migrates the organization settings info form from MUI TextField to
shared FormField/Input/Textarea patterns, and splits the page view into
focused section components so info, workspace sharing, and delete are no
longer one monolithic file.

Behavior is unchanged; this is structure and component migration only.

- Replace MUI TextField with FormField for slug and display name, plus a
Textarea for description
- Extract OrganizationInfoForm, WorkspaceSharingSection, and
DeleteOrganizationSection
- Move sharing dialog Storybook coverage onto WorkspaceSharingSection
2026-08-11 01:35:12 +00:00
McKayla はな efd5ce3668 test: fix failing storybook stories (#27674) 2026-08-10 17:03:28 -06:00
Andrew Aquino 87fdd2b59b feat(site): add server-side search and pagination for groups page (#27994)
Repeat of #27604, which I had mistakenly manually merged into #27603,
instead of letting Graphite handle it after #27603 merges into main.
Reattempting with GitHub stacks now instead of Graphite!

See #27604 for details/review.
2026-08-10 13:23:14 -07:00
Andrew Aquino 6e07e2610f feat: add paginated API endpoint for groups (#27603)
backend-only changes from #27271; see that PR for summary of changes +
implementation details
2026-08-10 13:23:14 -07:00
McKayla はな ddb2799009 fix: hide the favorite button for workspaces you don't own (#28000) 2026-08-10 14:15:57 -06:00
McKayla はな 09b0d8e108 chore: update stale Chromatic comments (#27714) 2026-08-10 14:15:28 -06:00
McKayla はな b29af7f64a fix: improve layout of CLI install page (#27998) 2026-08-10 14:03:04 -06:00
Jeremy Ruppel baa1e3a6c5 fix(site): make delete dialog confirmation text use primary color (#28002)
## Summary

In the workspace delete confirmation dialog, the text typed into the
"Workspace name" confirmation field rendered in the same secondary color
as the placeholder, making it hard to distinguish entered text from the
placeholder.

The shared `Input` component uses `text-inherit`, so it picked up the
dialog description's secondary text color. This sets the confirmation
input's text to `text-content-primary` (white on dark), while the
placeholder remains `text-content-secondary`.

## Changes

- `WorkspaceDeleteDialog.tsx`: add `className="text-content-primary"` to
the confirmation `Input`.


##### Before


https://github.com/user-attachments/assets/88dbb230-feb6-416c-b516-9cc92950a0b8

##### After


https://github.com/user-attachments/assets/74296b9e-cbdf-40fe-ba3d-6fbcf5d4a9d5

---

_This PR was generated by Coder Agents on behalf of @jeremyruppel._
2026-08-10 15:57:51 -04:00
Susana Ferreira 27414788f7 chore: use 'AI spend' and 'approximate' in budget UI (#27977)
The "AI budget" column shows spend against the configured limit, not the
limit itself, so "AI spend" describes what it actually displays. Renamed
in both the groups table and the group members table.

Also replaces "estimated" with "approximate" in the surrounding spend
copy, which reads more plainly as a signal that the amount isn't exact.

The user dropdown now keeps the date range on a single line, so the
label wraps above it instead of the dates splitting across two lines.

Before:
<img width="250" height="89" alt="Screenshot 2026-08-10 at 12 55 55"
src="https://github.com/user-attachments/assets/428f7032-0ead-44ac-987d-563e20c97d12"
/>

After:
<img width="248" height="92" alt="Screenshot 2026-08-10 at 12 57 09"
src="https://github.com/user-attachments/assets/cf0704ba-d0ab-4132-b207-a15ab2ea4f37"
/>

Related to internal slack thread:
https://codercom.slack.com/archives/C096PFVBZKN/p1786051712464009

> [!NOTE]
> Initially generated by Claude Opus 5, modified and reviewed by
@ssncferreira
2026-08-10 16:08:06 +01:00
Thomas Kosiewski 84f4a8bb17 fix(site/src): prevent protocol-relative login redirects (#27363) 2026-08-10 15:35:06 +02:00
Steven Masley 9a57dfa642 feat: include agent metadata in workspace list responses (#27934)
Closes #27933. Related: #27897 (single-agent GET).

Agent metadata is only readable via a per-agent watch stream, so reading
it across N workspaces costs N+1 requests. This adds a batch read to the
list endpoint:

```text
GET /api/v2/workspaces?q=param:"pool=demo" include_agent_metadata:task_status
```

- New `include_agent_metadata` search key, repeatable and key-scoped. It
expands the response, it does not filter workspaces.
- `GetWorkspaces` aggregates the requested keys as JSON behind a `CASE`:
without opt-in the response is unchanged and the subquery never runs.
Runs only for the returned page, inside the same authorized query.
- Agents in the response gain `metadata`
(`[]codersdk.WorkspaceAgentMetadata`, `omitempty`), mapped by the
`workspace_agent_id` each element carries. The collection script is
omitted; it can be long.
- `codersdk.WorkspaceFilter` gains `IncludeAgentMetadata []string`.
- No wildcard, no schema change, no migration.

---

Authored by Coder Agents on behalf of @Emyrk.
2026-08-10 08:13:32 -05:00
Matt Vollmer a3a51228ee chore(site): remove Beta tag from agents navigation (#27986)
## Summary

Removes the `Beta` feature stage badge from the `/agents` page
navigation:

- **`ChatsPanel.tsx`**: removed the badge from the desktop left sidebar
header
- **`AgentPageHeader.tsx`**: removed the badge from the mobile top
header

Both instances rendered `<FeatureStageBadge contentType="beta" size="xs"
/>` next to the Coder product logo. The `FeatureStageBadge` imports were
removed as they are no longer used in these files.

## Sidebar summary

- Removed Beta badge from desktop sidebar (`ChatsPanel.tsx`)
- Removed Beta badge from mobile header (`AgentPageHeader.tsx`)
- Removed unused `FeatureStageBadge` imports from both files
- No behavioral or logic changes, badge-only removal

---

PR generated with Coder Agents
2026-08-10 08:44:56 -04:00
Danielle Maywood 192842c8f2 fix(site/src): treat chat deleted watch events as archive instead of eviction (#27921) 2026-08-10 09:29:38 +01:00
Danielle Maywood 19fdc23d63 fix(site/src): fan chat message upserts out to every containing page (#27912) 2026-08-10 09:08:05 +01:00
Jake Howell bab9963a9a fix(site): defer external app API key generation to on-click (#27907)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Resolves
[DEVEX-460](https://linear.app/codercom/issue/DEVEX-460/defer-api-key-generation-in-useapplink-to-on-click-instead-of-page).

## Problem

`useAppLink` minted a session key on mount via a `useQuery`:

```ts
const { data: apiKeyResponse } = useQuery({
  ...apiKey(),
  enabled: isExternalApp(app) && needsSessionToken(app),
});
```

Whenever any page mounted `useAppLink` for an external app that embeds
`$SESSION_TOKEN` in its URL (JetBrains Gateway, Coder Desktop, etc.), it
fired `POST /api/v2/users/me/keys` on render, even if the user never
clicked the link. Each call minted a fresh session key and produced a
`created token` audit-log entry. Simply navigating the dashboard
generated a stream of `created token` entries with no real connection
activity.

This is the follow-up to #22318 (AIGOV-24), which only fixed the
built-in VS Code / VS Code Insiders buttons in `WorkspacesTable`.

## Change

Mirror the on-click minting pattern from #22318, applied to the shared
`useAppLink` hook:

- Replace the eager `useQuery(apiKey())` with a `useMutation(() =>
API.getApiKey())` that runs only when the user clicks a token-bearing
external app. `onClick` mints the key, builds the final URL, and
navigates via `location.href` (these are always custom-protocol,
non-HTTP external apps).
- The returned `href` no longer embeds a token; the hook owns opening
for token apps.
- Replace the `hasToken` field with `isLoading` (mint in-flight) and
update call sites so token apps are always clickable, with a loading
affordance while a key is being minted.
- `TaskApps` external-app menu items now render an anchor with the
hook's `onClick` (instead of a `RouterLink` that bypassed it), so the
deferred mint runs there too.

No API key is minted until the user actually opens an external app.

## Affected call sites

- `site/src/modules/apps/useAppLink.ts` (core change)
- `site/src/modules/resources/AppLink/AppLink.tsx`
- `site/src/pages/AgentsPage/components/WorkspacePill.tsx`
- `site/src/pages/TaskPage/TaskApps.tsx`

## Testing

Added Storybook interaction tests (`play` functions) in
`AppLink.stories.tsx` that assert the fix directly:

- `ExternalAppDefersSessionToken`: a token-bearing external app mints
**no** key on render, and mints exactly one on click.
- `ExternalAppWithoutSessionTokenNeverMints`: an external app without
`$SESSION_TOKEN` never mints a key, even on click.

Also verified:

- `tsc -p .` (frontend typecheck) passes
- `biome check` on changed files passes
- `vitest` for `AppLink` (incl. new stories), `apps`, `WorkspacePill`,
`TaskApps`, and `AppStatuses` stories/tests pass
- pre-commit hook (gen/fmt/lint/build) passes

## Manual verification checklist (recommended before merge)

- With an external app that uses `$SESSION_TOKEN` (e.g. JetBrains
Gateway), open DevTools → Network filtered on `users/me/keys`, reload
`/workspaces` and the workspace detail page, and confirm **no** `POST`
fires on render.
- Confirm a `POST` fires only when the app link is clicked, and the app
opens correctly.
2026-08-10 14:44:35 +10:00
Jake Howell b2cfc4e530 refactor(site): move Add users into <SettingsHeader /> (#27906)
Move the Add users action into SettingsHeader on the organization
Members page and group detail page, matching the Users page layout. It
no longer sits inline with the filters.

| Old | New |
| --- | --- |
| <img width="2934" height="1742" alt="ORGANIZATION_MEMBERS_OLD"
src="https://github.com/user-attachments/assets/c09ccb0b-cce5-4b95-a63b-40c42dd2e1ac"
/> | <img width="2934" height="1742" alt="ORGANIZATION_MEMBERS_NEW"
src="https://github.com/user-attachments/assets/a20089b7-04f0-47dc-8153-8f5cca8999cf"
/> |
2026-08-08 18:03:43 +10:00
Jake Howell ad225269aa refactor(site): redesign <AppearanceSettingsPage /> (#27722)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

- Redesign Deployment Appearance settings to the standard two-column
settings layout (`HorizontalForm` / `FormSection`) for branding, with
announcement banners as a secondary `SettingsHeader` + table section
(aligned with OAuth2 apps / AI Governance).
- Demui `IconField` and reuse it for Logo URL (URL input, preview, emoji
picker); thin `IconPickerField` to wrap the shared component.
- Clean up announcement banner create/edit (draft-only until save,
page-top preview via portal, shadcn `Switch` / menu icons, empty-state
CTA) and clarify Premium paywall copy to cover branding and announcement
banners.

| Old | New |
| --- | --- |
| <img width="2936" height="2666" alt="appearancesettings_old"
src="https://github.com/user-attachments/assets/db11950d-2440-412b-a74d-fcf57f2467e9"/>
| <img width="2936" height="2714" alt="appearancesettings_new"
src="https://github.com/user-attachments/assets/3f418fb1-7f94-4fd8-bf54-0d63014c6533"/>
|
2026-08-08 18:03:31 +10:00
Danielle Maywood e751b285ca chore(site): upgrade pierre diffs to 1.3.3 (#27932) 2026-08-07 11:38:56 +01:00