mirror of
https://github.com/coder/coder.git
synced 2026-11-03 05:55:24 +08:00
5699f1cdfb829da7cbeeb74fcb38ac70032afda1
5626
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5699f1cdfb |
fix: retry and cache e2e Coder release downloads to reduce test-e2e ssh flake (#27470)
closes DEVEX-651 ## Summary Fixes coder/internal#218 (`flake: e2e-test / test ssh`). Despite the title, the `ssh with client v2.8.0` / `ssh with agent v2.12.1` cases (`site/e2e/tests/outdatedCLI.spec.ts`, `outdatedAgent.spec.ts`) are not failing because of a bug in SSH. They fail during **setup**, in `downloadCoderVersion()`, which runs `install.sh` to fetch an old Coder release from GitHub. Transient GitHub errors (HTTP 403/503, surfacing as nonzero `curl` exit codes such as 22 or 1) make `install.sh` fail and take the whole ssh test down with it. This is an external-download flake, confirmed by the recurring `install.sh failed with code {22,1}` evidence in the issue thread and Ethan's note ("Networking issues again"). ## Changes 1. **Retry-with-backoff** (`site/e2e/helpers.ts`): `downloadCoderVersion()` now retries `install.sh` up to 5 times with exponential backoff and jitter (~1s, 2s, 4s, 8s). A single transient download failure no longer fails the test. `install.sh` already reuses completed binaries and resumes partial downloads (`curl -C -`), so retries are cheap. 2. **Cross-run cache** (`.github/workflows/ci.yaml`): the `test-e2e` job now persists `/tmp/coder-e2e-cache` with `actions/cache`, so most runs skip the GitHub download entirely. The key is derived from the spec files that pin the downloaded versions, so it invalidates when those versions change. Saves are restricted to `main` (`restore` runs everywhere), matching the existing cache-poisoning convention used for the Vale and golangci-lint caches. Before this change, neither retry, mirror, nor cross-run caching protected this path; the only caching was within a single run. ## Testing - `biome check e2e/helpers.ts` passes. - `tsc --noEmit` introduces no new errors. - CI `test-e2e` exercises the changed path. <details> <summary>Investigation notes</summary> - The failure always originates in `downloadCoderVersion` -> `install.sh` -> `fetch()` (`curl -#fL ... https://github.com/coder/coder/releases/download/vX.Y.Z/...`). - `curl` exit 22 = server returned an HTTP error (403 seen in logs); exit 1 = other transient failure. GitHub also returned 503s across the workflow in some occurrences. - `/tmp/coder-e2e-cache` was not persisted by any `actions/cache` step in `ci.yaml`, so every fresh job re-downloaded from GitHub and was exposed to the flake. - Retry addresses transient failures; the cache removes the dependency on GitHub for most runs. Combined, they target the root cause at two layers. </details> --- This PR was generated by Coder Agents on behalf of @aqandrew. |
||
|
|
ce4ee923c2 |
feat: notify users when AI spend crosses the budget threshold (#27346)
Implements: https://linear.app/codercom/issue/AIGOV-289/notify-users-and-admins-on-budget-warning-and-limit-reached Notify users when their AI spend crosses a budget threshold for their effective group. Two thresholds are covered: a warning at 85%, and a limit-reached notification at 100%. Detection runs on the post-response path, right after the interception's cost is added to the user's daily spend. It reads the user's AI spend on the same transaction where token usage is recorded and AI daily spend is incremented, and derives the pre-interception total by subtracting this interception's cost. In case of `oldSpend < threshold && newSpend >= threshold` - notification is sent. A single interception that crosses both thresholds enqueues both notifications. Detection and delivery are best-effort: a failure is logged and never fails usage recording. The payload uses only stable values (the threshold percentage and the spend limit, not the exact spend), so duplicate enqueues are deduplicated by the notification system. The two templates are added via migration and appear in each user's notification settings under the "AI Budget" group. Admin notifications (owners and user admins) are a follow-up: #27415. ## Screenshots: <img width="1102" height="252" alt="image" src="https://github.com/user-attachments/assets/62291510-09ca-4cdf-a1f5-4bdc11a1db4b" /> <img width="466" height="384" alt="image" src="https://github.com/user-attachments/assets/030460ff-6fe2-4d59-b247-3550c543ef30" /> --------- Co-authored-by: Cian Johnston <cian@coder.com> |
||
|
|
60c20be46f | chore(site): remove beta labels from user secrets dashboard (#27512) | ||
|
|
fd2faaa2f8 | refactor(site/src/pages/AgentsPage): drop defensive code for impossible chat states (#27513) | ||
|
|
6f2011af88 |
feat: add chat summary tab in the right sidebar and per-chat cost endpoint (#26649)
Stacked on #26657 (the persisted whole-chat summary backend). Base branch is `chat-summary-62j9`; review/merge that first. Adds a reusable `ChatSummary` component. The summary text is the persisted whole-chat summary (`chat.summary`) introduced by #26657. It is generated asynchronously and may be `null` until the first summary is produced, in which case the popover renders a muted empty state. Live updates arrive via that PR's `chat_summary_change` watch event, which is already merged into the chat caches. Cost is served by a new per-chat endpoint, `GET /api/experimental/chats/{chat}/cost`, which rolls up assistant-message cost across a chat's root and child (subagent) chats and is authorized like the other `{chat}` routes (read on the chat, 404 otherwise). Visual and interaction coverage lives in `ChatSummary.stories.tsx` and `ChatSummaryPopover.stories.tsx` (including populated-summary, empty-state, and cost-loading cases). --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
88c7304e0b |
feat: add AppearanceProvider to decouple externalImages from theme (#27197)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.
## What
Introduces an `AppearanceProvider` / `useAppearance` context that
publishes **user** appearance values derived from the active site theme,
and migrates the current consumers of `theme.externalImages` (`Avatar`,
`ExternalImage`, `IconsPage`) to read from it.
## Why
Today, per-user appearance concerns like `externalImages` are smuggled
onto the Emotion theme object, which forces components to pull in
`useTheme` purely to reach a single appearance value. That couples "how
something looks for this user" to "how the styling engine happens to be
wired", and means every new user-appearance value has to be bolted onto
the theme.
This context gives user appearance a home of its own, decoupled from
Emotion. Components ask for what they actually need (`const {
externalImages } = useAppearance()`) instead of reaching through the
theme.
## Scope: user appearance, not admin appearance
To be explicit, this provider is about **user-level** appearance — the
per-user, theme-derived rendering concerns. It is deliberately *not* the
deployment-level `AppearanceConfig` (application name/logo, service
banners, support/docs links) that admins configure; that is a separate
concern with its own data source and shouldn't be folded in here.
## Future scope
`externalImages` is the **first** value to move here, not the only one.
`Appearance` is deliberately modelled as an open interface so future
*user* appearance state can live in one place without touching every
consumer or overloading the theme again. Likely candidates are other
per-user, theme-derived values, e.g.:
- Terminal font / other typography preferences currently surfaced via
user appearance settings.
- Theme mode and other theme-derived rendering styles that follow the
same "read one value off the theme" pattern as `externalImages`.
- Accessibility-oriented rendering preferences (e.g. reduced motion) as
they're added.
Centralising these behind a single provider keeps consumers stable as
the surface grows and avoids re-litigating the `useTheme` coupling each
time (laziness now, less maintenance later).
## Changes
- Add `site/src/theme/appearance.tsx` (`AppearanceProvider`,
`useAppearance`), defaulting `externalImages` to `forDarkThemes` to
match `DEFAULT_THEME`.
- Wrap children with `AppearanceProvider` in `ThemeOverride` and in the
Storybook preview decorator.
- Migrate `Avatar`, `ExternalImage`, and `IconsPage` off
`theme.externalImages` and onto `useAppearance`.
## Notes
- Kept as a **draft** pending the go-ahead to open for review.
- No behavioural change intended; this is a plumbing/refactor step.
|
||
|
|
54bdb48cac |
fix(site): revert vite bump to 8.0.10 (#27504)
Vite 8.0.14–8.0.16 pulls in a Rolldown regression that emits calls to `init_emotion_react_browser_development_esm` without importing it, which crashes the site in `vite`/dev (`Uncaught ReferenceError`). Revert [#27485](https://github.com/coder/coder/pull/27485) (`8.0.10 → 8.0.16`) back to Vite 8.0.10 until we can bump to Vite >= 8.1.0, which includes the Rolldown fix. |
||
|
|
9e2fa105de |
fix: wrong border with in <WorkspaceBuildLogsSection /> (#27507)
I caught this earlier today, annoyed me. `border-width` was coming through wrong due to the use of just a `border-solid`. | Old | New | | --- | --- | | <img width="1220" height="480" alt="PREVIEW_BUILD_LOGS_OLD" src="https://github.com/user-attachments/assets/1a2bbf48-3b65-49b6-9a29-8dc1ac587d0d" /> | <img width="1028" height="475" alt="PREVIEW_BUILD_LOGS_NEW" src="https://github.com/user-attachments/assets/3dcf00b2-4bcb-4588-adbd-ac219e981813" /> | | <img width="220" height="220" alt="build-logs-corner-old" src="https://github.com/user-attachments/assets/97e03646-2625-4a2b-abfc-0f325fe197d1" /> | <img width="220" height="220" alt="build-logs-corner-new" src="https://github.com/user-attachments/assets/4fd90c9a-0487-49b8-a0b3-4c2f05aa8c92" /> | |
||
|
|
6120fb5988 | refactor(site): clean up workspace and template settings layouts (#25209) | ||
|
|
320817fa30 |
chore: bump postcss from 8.5.15 to 8.5.18 in /site (#27486)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.18. <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.18</h2> <ul> <li>Restricted loading previous source maps file to the <code>opts.from</code> folder for security reasons (use <code>unsafeMap: true</code> to disable the check).</li> </ul> <h2>8.5.17</h2> <ul> <li>Fixed <code>Maximum call stack size exceeded</code> error.</li> <li>Fixed Prototype hijacking for <code>postcss.fromJSON()</code>.</li> <li>Fixed <code>Input#origin()</code> for unmapped end position (by <a href="https://github.com/chatman-media"><code>@chatman-media</code></a>).</li> </ul> <h2>8.5.16</h2> <ul> <li>Fixed <code>Input#origin()</code> position (by <a href="https://github.com/mizdra"><code>@mizdra</code></a>).</li> <li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a href="https://github.com/sarathfrancis90"><code>@sarathfrancis90</code></a>).</li> <li>Fixed putting parent-less node in <code>nodes</code> of new node (by <a href="https://github.com/MahinAnowar"><code>@MahinAnowar</code></a>).</li> <li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by <a href="https://github.com/greymoth-jp"><code>@greymoth-jp</code></a>).</li> <li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a href="https://github.com/sarathfrancis90"><code>@sarathfrancis90</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.18</h2> <ul> <li>Restricted loading previous source maps file to the <code>opts.from</code> folder for security reasons (use <code>unsafeMap: true</code> to disable the check).</li> </ul> <h2>8.5.17</h2> <ul> <li>Fixed <code>Maximum call stack size exceeded</code> error.</li> <li>Fixed Prototype hijacking for <code>postcss.fromJSON()</code>.</li> <li>Fixed <code>Input#origin()</code> for unmapped end position (by <a href="https://github.com/chatman-media"><code>@chatman-media</code></a>).</li> </ul> <h2>8.5.16</h2> <ul> <li>Fixed <code>Input#origin()</code> position (by <a href="https://github.com/mizdra"><code>@mizdra</code></a>).</li> <li>Fixed <code>raws</code> after rehydrating a JSON AST (by <a href="https://github.com/sarathfrancis90"><code>@sarathfrancis90</code></a>).</li> <li>Fixed putting parent-less node in <code>nodes</code> of new node (by <a href="https://github.com/MahinAnowar"><code>@MahinAnowar</code></a>).</li> <li>Fixed computing <code>offset</code> in <code>positionBy()</code> (by <a href="https://github.com/greymoth-jp"><code>@greymoth-jp</code></a>).</li> <li>Fixed <code>rangeBy()</code> on <code>index: 0</code> (by <a href="https://github.com/sarathfrancis90"><code>@sarathfrancis90</code></a>).</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/postcss/postcss/commit/4c0d194c136fd374495d0993c890d794cab65b81"><code>4c0d194</code></a> Release 8.5.18 version</li> <li><a href="https://github.com/postcss/postcss/commit/92b4e7891ec7b811821d01acc8aa0f010caf41e2"><code>92b4e78</code></a> Update dependencies</li> <li><a href="https://github.com/postcss/postcss/commit/95663d3eb7ba26f4854dd19d3b4f4425760cf56c"><code>95663d3</code></a> Limit where source map can be loaded for security reasons</li> <li><a href="https://github.com/postcss/postcss/commit/74e25ae9f4efaa56a41a449064a655d7da78072c"><code>74e25ae</code></a> Release 8.5.17 version</li> <li><a href="https://github.com/postcss/postcss/commit/d1518afd5a88f42728b30b87f8917210f363f9f1"><code>d1518af</code></a> Fix Maximum call stack size exceeded error</li> <li><a href="https://github.com/postcss/postcss/commit/2421312ffea96ba77b35ce24a1b2d9c2e22b5e83"><code>2421312</code></a> Fix linter</li> <li><a href="https://github.com/postcss/postcss/commit/a50352c583df991710f92ccac25b36304695161a"><code>a50352c</code></a> Fix CI</li> <li><a href="https://github.com/postcss/postcss/commit/33948f0969bb858acdd52c9692e3a785a3ed0a73"><code>33948f0</code></a> Prevent prototype hijacking in fromJSON</li> <li><a href="https://github.com/postcss/postcss/commit/2131909351161cd2c5fc2be58b14919a873ea824"><code>2131909</code></a> Update dependencies</li> <li><a href="https://github.com/postcss/postcss/commit/93440abcca92793b31c5d1fdf5f2da7b58b27599"><code>93440ab</code></a> Fix non-closed <code>\<div align="center"></code> in README (<a href="https://redirect.github.com/postcss/postcss/issues/2110">#2110</a>)</li> <li>Additional commits viewable in <a href="https://github.com/postcss/postcss/compare/8.5.15...8.5.18">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for postcss since your current version.</p> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
dd794101cb |
chore: bump vite from 8.0.10 to 8.0.16 in /site (#27485)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.10 to 8.0.16. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/releases">vite's releases</a>.</em></p> <blockquote> <h2>v8.0.16</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.16/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v8.0.15</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.15/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v8.0.14</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.14/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v8.0.13</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.13/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v8.0.12</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.12/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v8.0.11</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v8.0.11/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's changelog</a>.</em></p> <blockquote> <h2><!-- raw HTML omitted --><a href="https://github.com/vitejs/vite/compare/v8.0.15...v8.0.16">8.0.16</a> (2026-06-01)<!-- raw HTML omitted --></h2> <h3>Bug Fixes</h3> <ul> <li><strong>deps:</strong> reject UNC paths for launch-editor-middleware (<a href="https://redirect.github.com/vitejs/vite/issues/22571">#22571</a>) (<a href="https://github.com/vitejs/vite/commit/50b951225bbf6151eb84a3ad5a454908ab4a76c9">50b9512</a>)</li> <li>reject windows alternate paths (<a href="https://redirect.github.com/vitejs/vite/issues/22572">#22572</a>) (<a href="https://github.com/vitejs/vite/commit/dc245c71e5007ea4d891a025e2d69ac96c736546">dc245c7</a>)</li> </ul> <h2><!-- raw HTML omitted --><a href="https://github.com/vitejs/vite/compare/v8.0.14...v8.0.15">8.0.15</a> (2026-06-01)<!-- raw HTML omitted --></h2> <h3>Features</h3> <ul> <li>send 408 on request timeout (<a href="https://redirect.github.com/vitejs/vite/issues/22476">#22476</a>) (<a href="https://github.com/vitejs/vite/commit/c85c9eeb9aaf41f477b48b057146887bd5620797">c85c9ee</a>)</li> <li>update rolldown to 1.0.3 (<a href="https://redirect.github.com/vitejs/vite/issues/22538">#22538</a>) (<a href="https://github.com/vitejs/vite/commit/646dbedd2870f8ec48df0321177d8aa64bbd1575">646dbed</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>capitalize error messages and remove spurious space in parse error (<a href="https://redirect.github.com/vitejs/vite/issues/22488">#22488</a>) (<a href="https://github.com/vitejs/vite/commit/85a0eff1c82bbb7c99a0fe8e63704316578a40d3">85a0eff</a>)</li> <li><strong>deps:</strong> update all non-major dependencies (<a href="https://redirect.github.com/vitejs/vite/issues/22511">#22511</a>) (<a href="https://github.com/vitejs/vite/commit/2686d7d0b722402204d3bcc687a87adea1bcf9fa">2686d7d</a>)</li> <li><strong>dev:</strong> fix html-proxy cache key mismatch for /@fs/ HTML paths (<a href="https://redirect.github.com/vitejs/vite/issues/21762">#21762</a>) (<a href="https://github.com/vitejs/vite/commit/47c4213f134f562c41ed7c031e4788510cf7e31e">47c4213</a>)</li> <li><strong>glob:</strong> error on relative glob in virtual module when no files match (<a href="https://redirect.github.com/vitejs/vite/issues/22497">#22497</a>) (<a href="https://github.com/vitejs/vite/commit/5c8e98f8b584ac5d42f0f9b8580c49792213b13c">5c8e98f</a>)</li> <li><strong>optimizer:</strong> close the rolldown bundle when write() rejects (<a href="https://redirect.github.com/vitejs/vite/issues/22528">#22528</a>) (<a href="https://github.com/vitejs/vite/commit/e3cfb9deecff563550fa1b8abd27656b8b292815">e3cfb9d</a>)</li> <li><strong>resolve:</strong> provide onWarn for viteResolvePlugin in JS plugin containers (<a href="https://redirect.github.com/vitejs/vite/issues/22509">#22509</a>) (<a href="https://github.com/vitejs/vite/commit/40985f1c09b7696e594e6c5695fbc315d2da2c83">40985f1</a>)</li> </ul> <h3>Miscellaneous Chores</h3> <ul> <li><strong>deps:</strong> update rolldown-related dependencies (<a href="https://redirect.github.com/vitejs/vite/issues/22566">#22566</a>) (<a href="https://github.com/vitejs/vite/commit/3052a67d9350f4c5076ab1c222c4a21a589cbcdd">3052a67</a>)</li> </ul> <h3>Code Refactoring</h3> <ul> <li>correct logic in <code>collectAllModules</code> function (<a href="https://redirect.github.com/vitejs/vite/issues/22562">#22562</a>) (<a href="https://github.com/vitejs/vite/commit/6978a9ceb942c4f5e211d52b8a1e569f8a65c80c">6978a9c</a>)</li> </ul> <h2><!-- raw HTML omitted --><a href="https://github.com/vitejs/vite/compare/v8.0.13...v8.0.14">8.0.14</a> (2026-05-21)<!-- raw HTML omitted --></h2> <h3>Features</h3> <ul> <li>update rolldown to 1.0.2 (<a href="https://redirect.github.com/vitejs/vite/issues/22484">#22484</a>) (<a href="https://github.com/vitejs/vite/commit/96efc88570b6a6ddf1a910f106920cbac07b3cf0">96efc88</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li><strong>deps:</strong> update all non-major dependencies (<a href="https://redirect.github.com/vitejs/vite/issues/22471">#22471</a>) (<a href="https://github.com/vitejs/vite/commit/98b81632139d51820f82036e58d6fbbf122b77b3">98b8163</a>)</li> <li><strong>dev:</strong> handle errors when sending messages to vite server (<a href="https://redirect.github.com/vitejs/vite/issues/22450">#22450</a>) (<a href="https://github.com/vitejs/vite/commit/e8e9a34dcf2540139de558a10187630884d10217">e8e9a34</a>)</li> <li><strong>html:</strong> handle trailing slash paths in transformIndexHtml (<a href="https://redirect.github.com/vitejs/vite/issues/22480">#22480</a>) (<a href="https://github.com/vitejs/vite/commit/5d94d1bffdb2a15de9341194d89baec86ce1f693">5d94d1b</a>)</li> <li><strong>optimizer:</strong> pass oxc jsx options to transformSync in dependency scan (<a href="https://redirect.github.com/vitejs/vite/issues/22342">#22342</a>) (<a href="https://github.com/vitejs/vite/commit/b3132dacea9c6e0cf526cd9f0f09d850f577c262">b3132da</a>)</li> </ul> <h3>Miscellaneous Chores</h3> <ul> <li><strong>deps:</strong> update rolldown-related dependencies (<a href="https://redirect.github.com/vitejs/vite/issues/22470">#22470</a>) (<a href="https://github.com/vitejs/vite/commit/7cb728eb629cc677661f1bc52a044ffc0b87fc7f">7cb728e</a>)</li> <li>remove irrelevant commits from changelog (<a href="https://github.com/vitejs/vite/commit/2c69495f250edf01132d4a20128de19dbe836086">2c69495</a>)</li> </ul> <h3>Code Refactoring</h3> <ul> <li><strong>glob:</strong> do not rewrite import path for absolute base (<a href="https://redirect.github.com/vitejs/vite/issues/22310">#22310</a>) (<a href="https://github.com/vitejs/vite/commit/0ae2844ab6d6d1ccf78a2975b8132769fc35b302">0ae2844</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/vitejs/vite/commit/f94df87ff03b40b65e29bacdc04cc18c7bccaa4a"><code>f94df87</code></a> release: v8.0.16</li> <li><a href="https://github.com/vitejs/vite/commit/dc245c71e5007ea4d891a025e2d69ac96c736546"><code>dc245c7</code></a> fix: reject windows alternate paths (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22572">#22572</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/50b951225bbf6151eb84a3ad5a454908ab4a76c9"><code>50b9512</code></a> fix(deps): reject UNC paths for launch-editor-middleware (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22571">#22571</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/8d1b0195fd186d0b3297d7cd17acff6c96797420"><code>8d1b019</code></a> release: v8.0.15</li> <li><a href="https://github.com/vitejs/vite/commit/2686d7d0b722402204d3bcc687a87adea1bcf9fa"><code>2686d7d</code></a> fix(deps): update all non-major dependencies (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22511">#22511</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/3052a67d9350f4c5076ab1c222c4a21a589cbcdd"><code>3052a67</code></a> chore(deps): update rolldown-related dependencies (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22566">#22566</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/e3cfb9deecff563550fa1b8abd27656b8b292815"><code>e3cfb9d</code></a> fix(optimizer): close the rolldown bundle when write() rejects (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22528">#22528</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/6978a9ceb942c4f5e211d52b8a1e569f8a65c80c"><code>6978a9c</code></a> refactor: correct logic in <code>collectAllModules</code> function (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22562">#22562</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/646dbedd2870f8ec48df0321177d8aa64bbd1575"><code>646dbed</code></a> feat: update rolldown to 1.0.3 (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22538">#22538</a>)</li> <li><a href="https://github.com/vitejs/vite/commit/85a0eff1c82bbb7c99a0fe8e63704316578a40d3"><code>85a0eff</code></a> fix: capitalize error messages and remove spurious space in parse error (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22488">#22488</a>)</li> <li>Additional commits viewable in <a href="https://github.com/vitejs/vite/commits/v8.0.16/packages/vite">compare view</a></li> </ul> </details> <br /> [](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) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/coder/coder/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
5fbb9c978d |
chore: bump react-router from 7.15.1 to 7.18.0 in /site (#27484)
Bumps [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) from 7.15.1 to 7.18.0. <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.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7180">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7180</a></p> <h2>v7.17.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7170">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7170</a></p> <h2>v7.16.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7160">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7160</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>v7.18.0</h2> <h3>Patch Changes</h3> <ul> <li>Fix server handler prerender responses when using <code>ssr: false</code> and <code>future.v8_trailingSlashAwareDataRequests: true</code>. Avoids false positive "SPA Mode" detection when serving prerendered paths (<a href="https://redirect.github.com/remix-run/react-router/pull/15173">#15173</a>)</li> <li>Use the <code>ServerRouter</code> nonce for nonce-aware SSR components when they don't provide their own value so strict CSP pages can load them. (<a href="https://redirect.github.com/remix-run/react-router/pull/15170">#15170</a>)</li> <li>Use <code>turbo-stream</code> to serialize and deserialize Framework Mode hydration errors (<a href="https://redirect.github.com/remix-run/react-router/pull/15175">#15175</a>)</li> <li>Precompute route branch matchers to avoid recompiling route path regexes during matching (<a href="https://redirect.github.com/remix-run/react-router/pull/15186">#15186</a>)</li> <li>Use the constructed request URL host when validating action request origins. (<a href="https://redirect.github.com/remix-run/react-router/pull/15185">#15185</a>)</li> <li>Remove the un-documented custom error serialization logic from Data Mode SSR built-in hydration flows (<a href="https://redirect.github.com/remix-run/react-router/pull/15175">#15175</a>)</li> <li>Validate protocols in RSC render redirects (<a href="https://redirect.github.com/remix-run/react-router/pull/15177">#15177</a>)</li> <li>Consolidate url normalization logic and better handle mixed slashes (<a href="https://redirect.github.com/remix-run/react-router/pull/15176">#15176</a>)</li> </ul> <h2>v7.17.0</h2> <h3>Minor Changes</h3> <ul> <li>Ship a subset of the official documentation inside the <code>react-router</code> package (<a href="https://redirect.github.com/remix-run/react-router/pull/15121">#15121</a>) <ul> <li>Markdown docs are now available in <code>node_modules/react-router/docs</code>, letting AI coding agents and the React Router agent skills read official docs locally</li> <li>Excludes auto-generated API docs (<code>api/</code>), <code>community/</code> content, and tutorials (<code>tutorials/</code>)</li> </ul> </li> </ul> <h2>v7.16.0</h2> <h3>Minor Changes</h3> <ul> <li>Stabilize <code>future.unstable_trailingSlashAwareDataRequests</code> as <code>future.v8_trailingSlashAwareDataRequests</code> (<a href="https://redirect.github.com/remix-run/react-router/pull/15098">#15098</a>)</li> </ul> <h3>Patch Changes</h3> <ul> <li> <p>Disable manifest path when lazy route dicovery is disabled (<a href="https://redirect.github.com/remix-run/react-router/pull/15068">#15068</a>)</p> </li> <li> <p>Fix browser URL creation to use the configured history window instead of the global window. (<a href="https://redirect.github.com/remix-run/react-router/pull/15066">#15066</a>)</p> <ul> <li>Pass the history/router window through to <code>createBrowserURLImpl</code> so custom window contexts keep the correct URL origin.</li> </ul> </li> <li> <p>Fix <code>useNavigation()</code> return type to preserve discriminated union across navigation states (<a href="https://redirect.github.com/remix-run/react-router/pull/15095">#15095</a>)</p> </li> <li> <p>Widen <code>MetaDescriptor</code> <code>script:ld+json</code> type from <code>LdJsonObject</code> to <code>LdJsonObject | LdJsonObject[]</code> to permit multiple JSON-LD schemas in a single <code><script type="application/ld+json"></code> tag emitted by <code><Meta /></code> (<a href="https://redirect.github.com/remix-run/react-router/pull/15082">#15082</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/remix-run/react-router/commit/6fb1e79f8304eddd8b78759edea83cb32389ebf5"><code>6fb1e79</code></a> Release v7.18.0 (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15187">#15187</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/09e6020d1950e54f361f7ad00938ecd4dde60929"><code>09e6020</code></a> Optimize route matching internals (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15186">#15186</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/5b57f5f371595ad97ac91cca389c5adc08ddcc3a"><code>5b57f5f</code></a> Request Host derivation + CSRF check simplifications (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15185">#15185</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/ce596e823f0d7b883a433af1d5a839a8b9fe0242"><code>ce596e8</code></a> Validate RSC redirect protocols (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15177">#15177</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/1cebd2a823bb232ad74dcb2d970f750070b2bebe"><code>1cebd2a</code></a> chore: format</li> <li><a href="https://github.com/remix-run/react-router/commit/9d22943fd46c8ae4b08236425fa3549e10e9ad1a"><code>9d22943</code></a> Use turbo stream for framework hydration errors (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15175">#15175</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/bf63729561365b50705a24fd576e293424df23ef"><code>bf63729</code></a> Consolidate url normalization logic (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15176">#15176</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/4ce8ff72737bcf43afc7e9f5705c9214a19ec9f6"><code>4ce8ff7</code></a> Fix prerendering pathname issue with trailingSlashAwareDataRequests e… (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15173">#15173</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/4f060dd11cd8bedcba9e3ee96fce832bd987fe25"><code>4f060dd</code></a> Use ServerRouter nonce when nonce prop is not specified (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/15170">#15170</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/3fce6d67f805a76b9c3e5a2f0352847ffb3355d2"><code>3fce6d6</code></a> Update docs on data router singleton</li> <li>Additional commits viewable in <a href="https://github.com/remix-run/react-router/commits/react-router@7.18.0/packages/react-router">compare view</a></li> </ul> </details> <br /> [](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) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/coder/coder/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
b8727d9c23 | fix: don't show admin settings dropdown to everyone (#27481) | ||
|
|
4f50b77ac5 |
fix: tweak Pill styles (#27475)
|
||
|
|
3cf97ff8e7 | fix: show selected owner's external auth when creating a workspace (#26653) | ||
|
|
d5a3963167 |
feat: add bulk user secret import endpoint and SDK client (PLAT-240) (#26724)
Adds `POST /api/v2/users/{user}/secrets/batch` and
`codersdk.Client.ImportUserSecrets` to import env, JSON, or YAML secrets
atomically. The endpoint validates each entry, rolls back the full batch
on conflicts or limits, omits secret values from responses and audit
logs, and imports keys that cannot be injected as environment variables
with an empty `env_name`.
Part of the [PLAT-240 bulk secret import
stack](https://linear.app/codercom/issue/PLAT-240). Reviewed and updated
by Coder Agents on behalf of @dylanhuff-at-coder.
|
||
|
|
10624122c5 |
feat(site/src): show spend for unlimited and zero AI budgets (#27458)
The group members table hid a member's spend behind a bare "Unlimited"
label when their budget resolves to a group with no limit, and rendered
a $0 budget as a special "None" label. Spend now always shows: as
"$X / Unlimited USD" for unlimited budgets, and as a normal limit row
("Group limit $0", exceeded color once spend is above zero) for $0
budgets.
The Everyone badge drops "(not allocated)" when the Everyone group's
own budget or a user override applies, showing "Everyone" or
"Everyone (individual)" instead. The not-attributed tooltip now states
that the amount is the user's spend in the viewed group and that their
AI budget is managed by another group, replacing the misleading
"Not attributed to this group" wording.
|
||
|
|
3c7a1d33e3 |
feat: add persisted whole-chat summary with background generation (#26657)
Adds a persisted whole-chat summary that backs the chat summary popover. A new nullable `chats.summary` column is populated in the background after a successful root-chat turn and pushed to clients via a new `chat_summary_change` watch event (distinct from `summary_change`, which is bound to `last_turn_summary`), so the popover reads `chat.summary` straight off the loaded `Chat` with no extra query. This is the data source for the popover and per-chat cost UI built in #26649; the popover can consume `chat.summary` once this lands (the field is nullable, so merge order does not matter). ## How it works - **Generation** runs in the existing successful-turn finalize hook, detached from the request so the user's turn is never blocked. A cadence gate generates the first summary after one completed turn, then regenerates every three turns, using the `chats.summary_generated_at` freshness marker. Generation reads compaction-aware history, renders it to a bounded plain-text transcript (short transcripts are skipped), and asks for a 1-3 sentence summary via structured output. Failures never clear an existing summary. - **Staleness** is guarded by `history_version` (mirroring `last_turn_summary`), so a background write racing a newer turn loses while worker lifecycle transitions cannot reject a fresh write. - **Model selection** uses the chat's configured model. ## Deferred to follow-ups - **Cost accounting**: the `chat_messages.cost_source` discriminator and summary/title usage recording were removed from this PR so summary persistence is not blocked by hidden accounting rows advancing `history_version`. Title usage recording stays on main's `InsertChatMessages` path. - **Model override**: deployment-wide summary generation model selection is split into #26803; the base feature always uses the chat model. ## Notes - Migration `000540` adds `chats.summary` and `chats.summary_generated_at`, and recreates `chats_expanded` to expose the new columns. - Root chats only; shared viewers pick up the summary on their next refetch (live watch events are owner-only). Refs #26649 --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
9ce366414e | fix(site): remember reasoning effort per model on new chat (#27457) | ||
|
|
c23f2c0223 |
feat: fall back to the Everyone group for AI spend attribution (#27364)
## Description Previously, a user with no per-user override and no membership in a budgeted group had no effective group, so their AI spend was attributed nowhere and was, therefore, untracked. This change falls back to the organization's Everyone group when no override or group budget applies. Since every user in an organization is implicitly a member of that org's Everyone group, spend is now attributed and tracked for any user with organization membership. A user with no organization membership resolves to no group, so their daily spend is not incremented and a warning is logged. The fallback is unlimited, so enforcement is unaffected: only override and group budgets can block requests. For users in multiple organizations, an existing budget on any Everyone group is still chosen by the "highest" policy; when none is budgeted, the fallback prefers the default org, then orders by organization name. ## Changes - Add `ResolveUserEffectiveGroup` and the `GetUserEveryoneFallbackGroup` query: resolve override → group budget → Everyone group fallback. - Attribute token-usage spend and the user AI spend endpoint via the fallback, so unbudgeted users resolve to their Everyone group instead of null. - Update `GetGroupMembersAISpend` to surface the Everyone fallback as the effective group. - Update `GetHighestGroupAIBudgetByUser` to break ties by organization name then group name, keeping multi-org resolution deterministic and consistent with the fallback. - For multi-org users with no budget anywhere, the fallback picks the Everyone group deterministically: prefer the default org, then order by organization name. Closes https://linear.app/codercom/issue/AIGOV-509/fall-back-to-the-everyone-group-for-spend-attribution > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
52a687902f |
docs: add frontend-review skill for pre-PR FE rule audits (#27408)
## What Adds `.claude/skills/frontend-review`, a diff-scoped self-review skill that audits changes under `site/src/` against the FE1 to FE10 rule contract before a PR is created or updated. Each rule has a concrete "what to look for in a diff" checklist, and the output format is a terse per-rule PASS/FAIL table with `file:line` findings. Wiring: - `site/AGENTS.md` Pre-PR Checklist gains step 6: run the audit when the diff touches `site/src/`. - `.claude/skills/code-review` now cites FE rule IDs for frontend findings. - The deep-review `frontend-reviewer` role audits against the same contract. ## Why Most frontend review findings are semantic (missing interaction coverage, clobbered form state, near-duplicate components) and cannot be linted. Today they are caught post-hoc by reviewers and the review bot, which is exactly the "PRs get complaints" experience. Running the same rubric before the PR exists converts review rounds into pre-push fixes. Stacked on #27407 (the rule contract). The deterministic-checks follow-up (#27409) was closed; that subset will be enforced through proper linting instead. > This PR was written by Mux, an AI coding agent, on behalf of Mike. |
||
|
|
5565fcd03b |
docs: add frontend pattern rule contract (FE1-FE10) (#27407)
## What
Adds `.claude/docs/FRONTEND_PATTERNS.md`, a canonical frontend rule
contract for `site/src/` with ten stable rule IDs (FE1 to FE10), each
with short incorrect/correct examples using real repo idioms. Adds a
compact non-negotiables index at the top of `site/AGENTS.md` and links
the contract from the root `AGENTS.md` frontend routing line.
## Why
Frontend PRs keep drawing the same review findings. Mining the last 18
months of `site/` PR review data (330 closed/merged PRs, 1,105 inline
comments, 358 actionable pattern findings across 57 PRs) shows the
recurring themes, in order of frequency: missing Storybook interaction
coverage, loose TypeScript, component duplication and PR scope,
redundant comments, unhandled UI states, accessibility, react-query
misuse, and effect misuse. The guidance largely existed in
`site/AGENTS.md` already, but as unprioritized prose with no shared
vocabulary.
Stable rule IDs give reviewers, agents, and tooling one shared language
("FE7: re-typed query key"), and the rules are ordered by how often
reviewers actually flagged them.
This is the first PR of a stack of two:
1. This PR: the rule contract.
2. A `frontend-review` skill that audits diffs against these rules
pre-PR (#27408).
A third PR with a deterministic ratchet script (#27409) was closed; the
machine-checkable subset will be enforced through proper linting
instead.
## Notes for reviewers
The rule content is derived from your own review comments (for example,
the re-typed query key example in FE7 mirrors feedback on #27385). If a
rule does not match how you want the frontend built, the contract file
is the place to change it.
> This PR was written by Mux, an AI coding agent, on behalf of Mike.
|
||
|
|
1c2bb07b81 | chore(site): upgrade to pixel 0.2 (#27353) | ||
|
|
6b22383823 |
fix(site/src/pages/TemplateBuilder): show all step content without inner scroll (#27437)
## Summary The Template Builder steps clipped their content to an inner scrollbar via `max-h-[calc(...)]` + `overflow-y-auto`, so the base picker showed fewer than three rows before requiring scroll. This removes those wrappers from all four steps so every base/module renders and the page scrolls naturally. Resolves DEVEX-585. ## Changes - `BaseInfraSelectStep.tsx` — base picker grid (3-col grid retained) - `ModuleSelectStep.tsx` — module picker grid - `ModuleSettingsStep.tsx` — module variables list - `BaseTemplateParametersStep.tsx` — base config; unwrapped the now-styleless wrapper `div` into the fragment The sticky sidebar summary (`SelectionSummary.tsx`) is intentionally left as-is; it is not a wizard step. ### Tradeoff With the inner scroll removed, the Back/Continue controls sit below the full grid, so reaching them requires page scroll when a list is long. This matches the requested "just show all of em" behavior. https://github.com/user-attachments/assets/7e371850-7b97-42c7-b92c-5ac00a3e7979 <details> <summary>Implementation plan</summary> # DEVEX-585: Show more base templates before requiring scroll ## Problem The base template picker on the Template Builder feels too narrow: it clips to fewer than three rows before an inner scrollbar appears. ## Root cause The step grids were wrapped in `max-h-[calc(100vh-420px)] overflow-y-auto` (and `340px` variants), constraining height so only a couple of rows showed before an inner scrollbar clipped the rest. ## Approach (chosen: remove inner scroll) Show all content and let the page scroll naturally by removing the height/scroll utilities (and stale comments) from each step's container. Applied to the base picker, base parameters, module picker, and module settings steps. ## Testing / verification - Biome check passes on all edited files; LSP reports no diagnostics. - Visual: each step renders all content with no inner scrollbar; the page scrolls if the list is long. ## Out of scope - The sidebar summary scroll (`SelectionSummary.tsx`) is not a wizard step. - Auto-filling customization fields (separate work, PR #27272). </details> --- This PR was generated by Coder Agents on behalf of @jeremyruppel. |
||
|
|
c309f4d5ff |
feat(site/src/pages/TemplateBuilder): auto-fill customization fields from base template (#27272)
Closes [DEVEX-586](https://linear.app/codercom/issue/DEVEX-586/auto-fill-customization-fields-from-selected-base-template). The Template Builder wizard's final **Customizations** step rendered empty inputs for ID, Display name, Description, and Icon. This seeds those fields with sensible defaults derived from the selected base template, while keeping every field editable. ## Changes All frontend, in `site/src/pages/TemplateBuilder/wizardState.ts`: - `SelectedBaseMeta` now carries `description`, mapped in `toSelectedBaseMeta`. - New pure helper `baseCustomizationDefaults(base)` maps the base to `{ name: base.id, displayName: base.name, description, icon }`. - `SET_BASE` seeds the four customization fields when the base changes (still clearing base variable values). Re-selecting the same base preserves user edits. - `initWizardState` seeds the same defaults for the `?base=` deeplink entry path. - `RESET_CUSTOMIZATIONS` (fired on back-navigation) now resets only organization/provisioner state, so auto-filled values survive stepping back and forth. No change was needed in `TemplateCustomizationsStep.tsx`; it already binds to these state fields, so seeded values render and stay editable. Existing placeholders remain as the fallback when a base value is empty (e.g. `scratch`). ### Default mapping | Form field | State key | Source | | ------------ | ------------- | ------------------ | | ID | `name` | `base.id` | | Display name | `displayName` | `base.name` | | Description | `description` | `base.description` | | Icon | `icon` | `base.icon` | `base.id` is used for the ID field because base ids are already valid template slugs (`docker`, `aws-linux`, ...). Icon values are already served asset paths (`/icon/*`, `/emojis/*`), so no lookup map is needed. ## Testing - `wizardState.test.ts`: 27 passing, including new coverage for seeding, base-change re-seed, same-base edit preservation, `RESET_CUSTOMIZATIONS`, `initWizardState`, `toSelectedBaseMeta`, and `baseCustomizationDefaults`. - `biome check` clean; `tsc --noEmit` clean. <img width="1043" height="593" alt="Screenshot 2026-07-15 at 2 17 19 PM" src="https://github.com/user-attachments/assets/25620df4-b020-4430-b5f3-9ce8b7b9f379" /> <details> <summary>Implementation plan</summary> # DEVEX-586: Auto-fill customization fields from selected base template ## Goal In the Template Builder wizard, the final **Customizations** step currently renders empty inputs for Display name, Description, ID, and Icon. Pre-populate these with sensible defaults derived from the selected base template, while keeping every field editable. Organization is already auto-selected when a single org is available, so it is out of scope beyond leaving it untouched. Source: Linear DEVEX-586 (Ben Potter): "Would love if all these options ... were auto-filled and generated and can be edited versus the user manually filling it out." Fields called out: display name, description, ID, and icon. ## Current behavior (findings) Frontend lives in `site/src/pages/TemplateBuilder/`. - `TemplateCustomizationsStep.tsx` renders the four fields bound to `state.displayName`, `state.description`, `state.name` (the "ID" field), and `state.icon`. All start empty (`initialWizardState`). - `wizardState.ts` holds the state, the `wizardReducer`, and the `SelectedBaseMeta` UI type. - `SelectedBaseMeta` did not carry `description`. - `toSelectedBaseMeta(base)` maps the API `TemplateBuilderBase` into `SelectedBaseMeta`. - `SET_BASE` set the base and cleared `baseVariableValues` only when the base id changed; customization fields were left empty. - `RESET_CUSTOMIZATIONS` (dispatched by `handleBack`) blanked org/provisioner plus `name`, `displayName`, `description`, `icon`. - `initWizardState(preselectedBase)` seeded `baseTemplateId` and `selectedBase` for deeplinks but left customization fields empty. - API type `TemplateBuilderBase` exposes `id`, `name`, `description`, `icon`, `os`, `variables`, `prerequisites`. - Backend (`coderd/templatebuilder_handler.go`) builds each base from the built-in `TemplateExample`: `id = ex.ID`, `name = ex.Name`, `description = ex.Description`, `icon = ex.Icon`. - Base IDs are valid template names (lowercase, hyphen-separated): `docker`, `kubernetes`, `aws-linux`, `aws-windows`, `gcp-linux`, `gcp-windows`, `azure-linux`, `digitalocean-linux`, `scratch`. ## Default mapping | Form field | State key | Default source | | --- | --- | --- | | ID (required) | `name` | `base.id` | | Display name | `displayName` | `base.name` | | Description | `description` | `base.description` | | Icon | `icon` | `base.iconUrl` (`base.icon`) | | Organization | `organizationId` | unchanged (already auto-selected) | Rationale for `name = base.id`: base ids are guaranteed valid template slugs, whereas slugifying the human display name is lossy and can collide. The field stays editable. ## Icon default: confirmed, no map needed The API already returns normalized, served asset paths in `base.icon` (e.g. `/icon/docker.png`, `/icon/aws.svg`, `/emojis/1f4e6.png` for `scratch`), the same values `CreateTemplatePage` assigns when creating from a built-in example. `IconField` accepts any URL/path, so every base renders correctly. A base-id-to-icon map is unnecessary. ## Implementation Frontend-only, in `wizardState.ts`: 1. Add `description?: string` to `SelectedBaseMeta`; map it in `toSelectedBaseMeta`. 2. Add pure helper `baseCustomizationDefaults(base)` returning `{ name, displayName, description, icon }`. 3. `SET_BASE`: on base change, spread the defaults alongside the `baseVariableValues: {}` reset; on same-base re-selection, preserve existing values. 4. `initWizardState(preselectedBase)`: spread defaults into the returned state. 5. Narrow `RESET_CUSTOMIZATIONS` to reset only `organizationId` and `hasProvisioners`. 6. `toCreateTemplateRequest` already sends the fields, so no payload change. ## Tests Reducer unit tests in `wizardState.test.ts` for seeding, base-change re-seed, same-base edit preservation, `RESET_CUSTOMIZATIONS`, `initWizardState`, `toSelectedBaseMeta` (description carried), and `baseCustomizationDefaults`. ## Scope / non-goals - No backend changes; the API already returns all needed fields. - Organization auto-selection is unchanged. - No slug transformation of display names (base id is used directly). - No base-id-to-icon map. </details> --- *Opened by Coder Agents on behalf of @jeremyruppel.* |
||
|
|
02fd1cc691 | feat: allow spawn_agent model and reasoning effort override (#27385) | ||
|
|
99e740bdb7 |
feat: add user secrets file parser and shared validator (PLAT-240) (#26723)
Part of the **PLAT-240** bulk secret import stack: this PR adds the `codersdk` parser and shared create-secret validator used by the follow-up batch endpoint and UI PRs. `ParseSecretsFile` parses `.env`, `.json`, and `.yaml` files into `CreateUserSecretRequest` entries in source order, with size, count, duplicate-key, structure, and malformed-input checks. `ValidateCreateUserSecretRequest` now backs the single-create handler too, so create validation has one SDK-level implementation. Part of https://linear.app/codercom/issue/PLAT-240 > This PR was generated by Coder Agents on behalf of @dylanhuff-at-coder. |
||
|
|
ff71bb3850 | fix(site): align AI Settings model provider dropdowns (#27391) | ||
|
|
f17d488479 |
feat: add network call badges to AI sessions table (#27341)
Surface the total and blocked Agent Firewall network calls on the AI sessions list. Sessions that did not pass through Agent Firewall show as "Disabled". <img width="2842" height="1366" alt="image" src="https://github.com/user-attachments/assets/2a68b4a9-4d93-454d-a06e-5f0d0b734a33" /> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
507ce504f8 | refactor(site): align AgentsPage layout naming with codebase conventions (#27378) | ||
|
|
6ec45f75c6 |
chore(site): replace handrolled AI spend types with generated types (#27342)
The groups and group members pages consumed AI spend through local ai_cost_control wrapper types with TODOs to adopt the generated contract. Both spend endpoints are now live, so this switches to the generated types and hardens the fetch path. - Use OrganizationGroupsAISpend and GroupMembersAISpend from typesGenerated for the org groups and group members spend endpoints - Fetch identity and spend separately, joining by group_id/user_id at the container so each row gets one enriched object - Batch spend requests at the backend cap of 100 IDs in the API client and merge the responses, with table-driven tests covering both endpoints - Treat a null effective_group_id as a budget managed by a group in another org: render an em-dash with an info tooltip and skip the group name lookup instead of firing an empty-ID request Closes AIGOV-509 |
||
|
|
608c2ee46f |
fix(site/src/pages/AgentsPage/components/ChatMessageInput): scroll skills menu selection into view (#27345)
When navigating the slash skills menu with arrow keys, moving the highlight past the visible area did not scroll the list, so the selected skill went out of view. The menu drives cmdk in controlled mode while arrow keys are consumed by the Lexical trigger plugin, so cmdk's internal scroll-into-view never runs for keyboard navigation. This adds a layout effect in `SkillsTriggerMenu` that scrolls the highlighted item (and its group heading when it is the first item in a group) into view on keyboard-driven index changes, while skipping pointer-driven highlights to avoid hover/scroll loops, matching cmdk's own behavior. Covered by two new interaction stories that fail without the fix: `ScrollsSelectionIntoView` (menu in isolation) and `ArrowKeysScrollMenuList` (end-to-end arrow-key wrap in `ChatMessageInput`). > Opened by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
dcf3cce51c |
fix(site/src/pages/AgentsPage): clarify empty context usage popover state (#27389)
## Summary The context usage badge popover showed "Context usage unavailable" before any assistant message reported token usage, which read like an error. This changes the empty-state copy to "Context usage will appear after sending a message." and fixes a spacing bug that state exposed: the pinned context list's top margin was conditional on a usage percentage being present, so without usage data the list sat flush against the message. ## Changes - `ContextUsageIndicator`: new empty-state copy; unconditional `mt-2` on the context list. - Stories: `NoUsage` (message only) and `NoUsageWithContext` (message plus pinned resource list), both asserting the new copy via hover interactions. ## Testing - Storybook interaction stories cover both empty states. - `biome check` and `tsc --noEmit` pass; verified visually in Storybook. > This PR was authored by Mux, an AI coding agent, acting on Mike's behalf. |
||
|
|
a9a1dcc65d |
feat: add network calls column to AI sessions table (#27269)
Add a "Total/blocked network calls" column to the AIBridge sessions table. Update `ListAIBridgeSessions` query to calculate network called made and blocked per session. See query plan [here](https://explain.dalibo.com/plan/54355c90b165ggb4). --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6014a44c85 | fix(site): keep mobile model picker effort row and last model visible (#27336) | ||
|
|
3227cac217 |
feat: add manual chat compaction via /compact (#27081)
Adds a user-triggered `/compact` action for Coder Agents chats: typing
`/compact` in the composer (or picking it from the `/` trigger menu)
summarizes the conversation so far to free up context window space.
## How it works
- New `POST /api/experimental/chats/{chat}/compact` endpoint
(owner-only, RBAC `ActionUpdate`, excluded from the public API reference
via `x-apidocgen skip`). It marks the chat with a durable one-shot
`chats.compaction_requested_at` signal and moves it `waiting -> running`
via a new `RequestCompaction` state transition; no message row is
inserted. AI Gateway attribution needs no per-request key: generation
preparation resolves the owner's synthetic API key (#27170) like any
other turn.
- `RequestCompaction` hands off chat ownership (clears
`worker_id`/`runner_id`) so a worker acquisition hint is published;
since the transition changes no history, the previous runner could
otherwise miss the request under reordered pubsub delivery.
- The background chat worker picks the chat up like any other turn. A
pending manual request takes precedence over turn completion in the
generation decision, and forces compaction even below the automatic
threshold (and when compaction is disabled via threshold=100). The
commit step consumes the request marker in the same transaction; any
transition that ends the turn clears stale markers.
- The summary triplet reuses the automatic-compaction path, now tagged
with a `source` (`automatic` | `manual`) that is plumbed through
streamed progress parts, persisted tool JSON, and the UI label
("Summarized (manual)").
- Validation order: busy chats reject with 409 (state-machine conflict),
empty/already-compacted chats with 409 "nothing to compact", archived
chats with 400; the owner usage-limit check runs last so no-op requests
surface the specific conflict instead of a limit error.
- Web UI: the `/` trigger menu now has a built-in "Commands" group
listing `/compact`; submit intercepts exactly `/compact` and calls the
endpoint instead of sending a message. A personal or workspace skill
named `compact` takes precedence over the built-in command; while skill
collisions are still resolving, an exact `/compact` submission is
blocked with a retryable hint instead of leaking as message text.
History and queued-message edits are never intercepted. After
compaction, the context usage indicator resets to its unknown state
until the next assistant response reports fresh usage, instead of
showing the stale pre-compaction number.
- codersdk: `ExperimentalClient.CompactChat`.
Worker-path execution (rather than compacting synchronously in the
handler) reuses the existing lock fencing, live "Summarizing..."
streaming, retry accounting, restart resilience, and debug-run
observability. Rationale documented in `coderd/x/chatd/ARCHITECTURE.md`.
## Testing
- State machine: transition-matrix coverage for `RequestCompaction`,
marker lifecycle tests (carried by lease renewals/queue appends, cleared
by terminal transitions, consumed by commit), ownership handoff +
acquisition hint assertions.
- Worker: decision-ordering and forced-compaction unit tests;
active-server end-to-end test (manual compact below threshold produces a
`source=manual` summary, returns to `waiting`, no assistant follow-up;
busy chat rejected).
- API: success, archived, non-owner, RBAC-denied, empty-chat, no-daemon
cases; usage-limit ordering (at-limit owners still get
state/nothing-to-compact conflicts for no-op requests, with marker
rollback).
- Frontend: Storybook play tests for the Commands menu group, submit
intercept, skill-name collision, queued-edit passthrough, and
manual/automatic tool rendering; unit tests for command availability
resolution and the post-compaction context usage reset.
> This PR was created by Mux, an AI coding agent, working on Mike's
behalf.
|
||
|
|
69a045f944 |
chore: bump axios from 1.16.1 to 1.18.0 in /site (#27350)
Bumps [axios](https://github.com/axios/axios) from 1.16.1 to 1.18.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/releases">axios's releases</a>.</em></p> <blockquote> <h2>v1.18.0 — June 13, 2026</h2> <p>This release hardens redirect and URL handling, improves the validateStatus configuration semantics, and includes updates to documentation, dependencies, and release metadata.</p> <h2>🔒 Security Fixes</h2> <ul> <li> <p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter support for stripping caller-specified sensitive headers on cross-origin redirects, helping prevent custom auth headers such as API keys from leaking to another origin. (<strong><a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p> </li> <li> <p><strong>URL And Request Hardening:</strong> Rejects malformed <code>http:</code> and <code>https:</code> URLs that omit <code>//</code> with <code>ERR_INVALID_URL</code>, while tightening prototype-pollution-safe config reads, stream size limits, FormData depth handling, data URL sizing, and local <code>NO_PROXY</code> matching. (<strong><a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p> </li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Status Validation:</strong> Added <code>transitional.validateStatusUndefinedResolves</code> so applications can opt in to treating <code>validateStatus: undefined</code> like the option was omitted, while <code>validateStatus: null</code> remains the explicit way to accept every status. (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li> <p><strong>Documentation:</strong> Published the v1.17.0 release notes, fixed a changelog typo, clarified the package update PR policy, and marked the <code>proxy</code> request config as Node.js-only in the advanced docs. (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p> </li> <li> <p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>, <code>@babel/preset-env</code>, <code>@commitlint/cli</code>, <code>@commitlint/config-conventional</code>, <code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>, <code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>, <code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>, <code>vitest</code>, and <code>actions/checkout</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p> </li> <li> <p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by updating package metadata and the runtime <code>VERSION</code> value. (<strong><a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p> </li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve axios:</p> <ul> <li><strong><a href="https://github.com/drori12"><code>@drori12</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li> <li><strong><a href="https://github.com/eyupcanakman"><code>@eyupcanakman</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> <li><strong><a href="https://github.com/Adi-Beker"><code>@Adi-Beker</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li> </ul> <p><a href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full Changelog</a></p> <h2>v1.17.0 — June 1, 2026</h2> <p>This release adds Node HTTP zstd decompression, hardens config and release workflows, and fixes authentication, header, proxy, and type-handling regressions.</p> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>, <code>params</code>, and <code>paramsSerializer</code> reads with own-property checks to prevent inherited prototype values from affecting request behavior, including SSRF-sensitive paths. (<strong><a href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li> <li><strong>Release Publishing:</strong> Switched the publish workflow to npm staged publishing for safer, auditable package releases with provenance. (<strong><a href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>HTTP Compression:</strong> Added Node HTTP adapter support for zstd response decompression, with <code>transitional.advertiseZstdAcceptEncoding</code> controlling whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Authentication Handling:</strong> Restored Basic auth on same-origin Node redirects while continuing to strip credentials cross-origin, and aligned the fetch adapter with HTTP adapter behavior for URL-embedded Basic auth. (<strong><a href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li> <li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code> TLS options when tunneling HTTPS requests through HTTP CONNECT proxies. (<strong><a href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li> <li><strong>React Native FormData:</strong> Cleared default <code>Content-Type</code> for React Native <code>FormData</code> so multipart boundaries can be generated correctly. (<strong><a href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's changelog</a>.</em></p> <blockquote> <h2>v1.18.0 — June 13, 2026</h2> <p>This release hardens redirect and URL handling, improves the validateStatus configuration semantics, and includes updates to documentation, dependencies, and release metadata.</p> <h2>🔒 Security Fixes</h2> <ul> <li> <p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter support for stripping caller-specified sensitive headers on cross-origin redirects, helping prevent custom auth headers such as API keys from leaking to another origin. (<strong><a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p> </li> <li> <p><strong>URL And Request Hardening:</strong> Rejects malformed <code>http:</code> and <code>https:</code> URLs that omit <code>//</code> with <code>ERR_INVALID_URL</code>, while tightening prototype-pollution-safe config reads, stream size limits, FormData depth handling, data URL sizing, and local <code>NO_PROXY</code> matching. (<strong><a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p> </li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Status Validation:</strong> Added <code>transitional.validateStatusUndefinedResolves</code> so applications can opt in to treating <code>validateStatus: undefined</code> like the option was omitted, while <code>validateStatus: null</code> remains the explicit way to accept every status. (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li> <p><strong>Documentation:</strong> Published the v1.17.0 release notes, fixed a changelog typo, clarified the package update PR policy, and marked the <code>proxy</code> request config as Node.js-only in the advanced docs. (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p> </li> <li> <p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>, <code>@babel/preset-env</code>, <code>@commitlint/cli</code>, <code>@commitlint/config-conventional</code>, <code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>, <code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>, <code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>, <code>vitest</code>, and <code>actions/checkout</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p> </li> <li> <p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by updating package metadata and the runtime <code>VERSION</code> value. (<strong><a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p> </li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve axios:</p> <ul> <li><strong><a href="https://github.com/drori12"><code>@drori12</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li> <li><strong><a href="https://github.com/eyupcanakman"><code>@eyupcanakman</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> <li><strong><a href="https://github.com/Adi-Beker"><code>@Adi-Beker</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li> </ul> <p><a href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full Changelog</a></p> <h2>v1.17.0 — June 1, 2026</h2> <p>This release adds Node HTTP zstd decompression, hardens config and release workflows, and fixes authentication, header, proxy, and type-handling regressions.</p> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>, <code>params</code>, and <code>paramsSerializer</code> reads with own-property checks to prevent inherited prototype values from affecting request behavior, including SSRF-sensitive paths. (<strong><a href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li> <li><strong>Release Publishing:</strong> Switched the publish workflow to npm staged publishing for safer, auditable package releases with provenance. (<strong><a href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>HTTP Compression:</strong> Added Node HTTP adapter support for zstd response decompression, with <code>transitional.advertiseZstdAcceptEncoding</code> controlling whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Authentication Handling:</strong> Restored Basic auth on same-origin Node redirects while continuing to strip credentials cross-origin, and aligned the fetch adapter with HTTP adapter behavior for URL-embedded Basic auth. (<strong><a href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li> <li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code> TLS options when tunneling HTTPS requests through HTTP CONNECT proxies. (<strong><a href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li> <li><strong>React Native FormData:</strong> Cleared default <code>Content-Type</code> for React Native <code>FormData</code> so multipart boundaries can be generated correctly. (<strong><a href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/axios/axios/commit/2d06f96e8602c2db13b65a26340ee4a1bbc0b61f"><code>2d06f96</code></a> chore(release): prepare release 1.18.0 (<a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a>)</li> <li><a href="https://github.com/axios/axios/commit/32fc489632377d214db55bfa4e2c48486a7d7ce2"><code>32fc489</code></a> fix: malformed http urls (<a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a>)</li> <li><a href="https://github.com/axios/axios/commit/b40ce498abfa10d90b873b4fd08f520afa5d2545"><code>b40ce49</code></a> chore(deps-dev): bump the development_dependencies group with 10 updates (<a href="https://redirect.github.com/axios/axios/issues/10">#10</a>...</li> <li><a href="https://github.com/axios/axios/commit/fe964f960ecb52c3e1155b0daf7be77541956b01"><code>fe964f9</code></a> docs: mark proxy config as Node.js only (<a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a>)</li> <li><a href="https://github.com/axios/axios/commit/5f229d2d1f018d1db3dab6bbe034dbf3f9041b99"><code>5f229d2</code></a> chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 in the github-actions ...</li> <li><a href="https://github.com/axios/axios/commit/fae9d4e7db6a858c407c75e607a071c533c5c4f6"><code>fae9d4e</code></a> docs: clarify package update PR policy (<a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a>)</li> <li><a href="https://github.com/axios/axios/commit/28ab2ced820e55192806c53472ab3eb0cbb68dc2"><code>28ab2ce</code></a> chore(deps-dev): bump the development_dependencies group with 2 updates (<a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a>)</li> <li><a href="https://github.com/axios/axios/commit/a8e4f13aeecc45a3b8fab3ecfd9ddb5d70fb772b"><code>a8e4f13</code></a> fix(core): keep default validateStatus when request passes undefined (<a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a>)</li> <li><a href="https://github.com/axios/axios/commit/614f4552a17de757d4171ad7c3bd38c9c1025fd8"><code>614f455</code></a> docs: publish v1.17.0 release notes (<a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a>)</li> <li><a href="https://github.com/axios/axios/commit/6bb12c191f5380fad321322fb90216ae0dc36985"><code>6bb12c1</code></a> fix: custom auth headers not stripped on cross-origin redirects (<a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a>)</li> <li>Additional commits viewable in <a href="https://github.com/axios/axios/compare/v1.16.1...v1.18.0">compare view</a></li> </ul> </details> <br /> [](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) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/coder/coder/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
f18c664be2 |
fix(site): stack settings layouts on mobile (#27334)
## Problem On mobile viewports every settings shell renders a fixed 240px sidebar next to the content in a non-responsive flex row, leaving the content almost no width. The MCP Servers page is worst: its fixed-layout table cannot shrink, so the whole page collapses into a single cramped column. ## Changes - `Sidebar` component: full width below the `lg` breakpoint, `w-60` at `lg`+. - Six settings layouts (AI, Deployment, Organization, User, Workspace, Template) stack the nav above the content below `lg` and keep the previous side-by-side spacing at `lg`+. Content wrappers get `min-w-0` so flex children cannot force overflow, and horizontal padding tightens on small screens. - MCP servers table gets `min-w-[640px]` so the existing `overflow-auto` wrapper provides horizontal scrolling instead of colliding column headers. Tailwind class changes only; no component or behavior changes. ## Testing - `pnpm check` and `pnpm run lint:types` pass. - Dogfood UAT on a dev deployment: at 390x844 the MCP Servers, Deployment, Account, and Template settings pages stack nav-above-content with no horizontal body overflow and a scrollable MCP table; boundary verified stacked at 1023px and side-by-side at 1024px; at 1440x900 the layouts are pixel-identical to before (240px sidebar, 112px gap, 40px padding). Closes CODAGT-828. > Created by Mux, an AI agent, on Mike's behalf. |
||
|
|
a9fdf87a2f |
feat: add GET /groups/{group}/members/ai/spend (#27130)
## Description
Adds `GET /api/v2/groups/{group}/members/ai/spend?user_ids=...` (also available org-scoped at `/api/v2/organizations/{org}/groups/{groupName}/members/ai/spend`) to return per-member AI spend attributed to a group, along with each member's effective budget group and the applied spend limit when the queried group is their effective budget source.
In the UI, this endpoint is used alongside the existing `/api/v2/groups/{group}/members` endpoint. AI spend data is kept separate from that endpoint so that:
- Different concepts stay on different endpoints: identity (group members) vs. cost control (spend). Cost control is an additional feature layered on top of groups/orgs.
- Callers that don't need spend information don't pay for its computation.
UI flow:
1. Request `/api/v2/groups/{group}/members` → returns the group's members.
2. Request `/api/v2/groups/{group}/members/ai/spend?user_ids=...` with the IDs from step 1.
**Note:** Only current members of the queried group are returned. `spend_limit_micros` and `limit_source` are populated only when the queried group is the member's effective budget source (its own limit or a user override). `effective_group_id` is null when the member's budget resolves to a group in another organization, since an organization is treated as a tenant boundary.
<img width="2880" height="1904" alt="image" src="https://github.com/user-attachments/assets/33ed395d-d1a3-4b46-bb04-c8d3f41c8886" />
## Changes
- Add `codersdk.GroupMembersAISpend` and `GroupMemberAISpend` types, reusing the shared `AISpendPeriodWindow`.
- Add `GetGroupMembersAISpend` SQL query with a dbauthz per-row filter that mirrors `GET /api/v2/groups/{group}/members`.
- Add handler and routes under `/groups/{group}/members/ai/spend` (and the org-scoped alias) with a required `user_ids` query param (cap 100). Callers with more than 100 members are expected to batch across multiple requests.
- Add codersdk client method.
- Tests: dbauthz, raw SQL, endpoint, and role-access.
Closes https://linear.app/codercom/issue/AIGOV-471/backend-group-members-endpoint-with-members-spend
> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira
|
||
|
|
2adc8f5272 |
feat: add GET /organizations/{org}/groups/ai/spend (#27123)
## Description
Adds `GET /api/v2/organizations/{org}/groups/ai/spend?group_ids=...` to return per-group AI spend and configured limits for a set of groups in an organization.
In the UI, this endpoint is used alongside the existing `/api/v2/organizations/{org}/groups` endpoint. AI spend data is kept separate from that endpoint so that:
- Different concepts stay on different endpoints: identity (groups) vs. cost control (spend). Cost control is an additional feature layered on top of groups/orgs.
- Callers that don't need spend information don't pay for its computation.
UI flow:
1. Request `/api/v2/organizations/{org}/groups` → returns the organization's groups.
2. Request `/api/v2/organizations/{org}/groups/ai/spend?group_ids=...` with the IDs from step 1.
The groups endpoint from 1) is currently not paginated, but if pagination is added later, this design keeps the two responses in sync. This spend endpoint intentionally takes `group_ids` rather than paginating on its own, since it depends on the group set from step 1. Pagination could be added in the future, especially for Cost Control-focused pages.
<img width="2880" height="1460" alt="image" src="https://github.com/user-attachments/assets/ea83b74d-6a4f-45a6-af2f-1024e019da07" />
## Changes
- Add `codersdk.OrganizationGroupsAISpend` and `OrganizationGroupAISpend` types, plus a shared `AISpendPeriodWindow` embedded in the spend response.
- Add `GetOrganizationGroupsAISpend` SQL query with a dbauthz per-row filter that mirrors `GET /organizations/{org}/groups`.
- Add handler and route under `/organizations/{organization}/groups/ai/spend` with a required `group_ids` query param (cap 100). Callers with more than 100 groups are expected to batch across multiple requests.
- Add codersdk client method.
- Tests: dbauthz, raw SQL, endpoint, and role-access.
Closes https://linear.app/codercom/issue/AIGOV-466/backend-organization-groups-endpoint-with-groups-spend
> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira
|
||
|
|
9f4ddea571 |
feat: revoke MCP server OAuth grants at the provider on disconnect (#27300)
Closes [CODAGT-805](https://linear.app/codercom/issue/CODAGT-805/revoke-oauth-grants-at-the-source-for-mcp-servers). The experimental MCP server OAuth2 disconnect endpoint previously deleted only the stored token row, leaving the grant active at the OAuth provider. This PR adds provider-side token revocation while keeping local disconnect independent of provider availability. ## Changes - Add `mcp_server_configs.oauth2_revocation_url` in migration `000547`. The value can be configured manually, discovered from RFC 8414 metadata, and managed through the MCP server settings UI. Non-admin responses redact it with the other OAuth2 fields. - Revoke the refresh token first through the RFC 7009 endpoint, then fall back to the access token only for `unsupported_token_type`. Public clients send `client_id`; confidential clients use `client_secret_basic`. - Delete the local token transactionally before best-effort provider revocation. Callers without a token receive the same response for hidden and nonexistent config IDs, and provider failures return a generic warning without exposing provider response bodies. - Require HTTPS revocation endpoints except for HTTP loopback URLs. Redirects must preserve the POST and remain on the configured origin. Redirect errors omit provider-controlled paths and query strings so reflected token material cannot enter logs. - Treat `200 OK` and `204 No Content` as completed revocations. `202 Accepted` remains a failure because it does not confirm completion. - Prevent an in-flight refresh from recreating a token deleted by disconnect. Refresh persistence now uses an optimistic update keyed by token ID and `updated_at`; only the OAuth callback can create a token row. Refresh conflicts reload the current row or clear in-memory auth when disconnect deleted it. - Return `{token_revoked, token_revocation_error}` from disconnect, while retaining SDK compatibility with the legacy `204` response. The UI surfaces provider revocation failures as warning toasts. - Document revocation endpoint discovery, HTTPS requirements, and best-effort disconnect behavior. No token or no configured revocation URL returns `token_revoked: false` without an error, so disconnect remains idempotent. > Updated by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
9b3af629cd | fix: hide and reject chat models from disabled AI providers (#27070) | ||
|
|
34ed124478 |
fix(site): align React Compiler check scope with vite.config.mts (#27216)
## Stack Context First PR of a 6-PR stack that thins the agent instruction corpus (~4,800 lines down to ~2,800) by removing startup bloat, assigning each procedure one canonical owner, and fixing rules that drifted from reality. Split from #27203 for reviewability. ## Why? `site/vite.config.mts` compiles `src/pages/AIBridgePage/` with the React Compiler, but `site/scripts/check-compiler.mjs` did not include that directory. Compiler regressions in AIBridgePage were invisible to CI: code could silently bail out of compilation with no signal. The two lists had already drifted once, which is exactly how this class of bug recurs. ## What? - Add `src/pages/AIBridgePage/` to the check-compiler scope. Verified all 381 functions in scope compile cleanly. - Cross-reference the two lists with comments so the next person who edits one finds the other. This is the only behavioral (non-docs) change in the stack, which is why it sits at the bottom. > This PR was prepared by Mux (AI agent) on Mike's behalf. |
||
|
|
1ea61b976b |
fix(site): prevent slash menu from flashing at top-left corner when closed (#27326)
Typing `/` in the agent chat input opens the skills slash menu. Pressing Backspace to erase the `/` made the menu flash at the top-left corner of the app for a split second before disappearing. Radix keeps the popover content mounted through its exit animation, but the caret-positioned `PopoverAnchor` was unmounted in the same render that closed the menu. Without an anchor, the popper repositioned the still-visible closing content to the viewport origin. The anchor now stays rendered at the last known caret rect, so the menu holds its position while it animates out. Verified with a frame-by-frame position recorder in the browser: before the fix the closing menu jumped from the caret position to `(0, 4)`; after the fix it stays in place until unmount. Added a `BackspaceClosesMenuWithoutRepositioning` story that fails without the fix. > This PR was created by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
46d1823c0a |
feat: add workspace skills to agent chat slash menu (#25600)
> This Pull Request was updated by Mux working on behalf of Mike. Adds workspace skills to the agent chat slash menu, sourced entirely from the chat's pinned context resources (the single-chat GET response the page already fetches), the same inventory `read_skill` resolves from. No new API endpoint is introduced. Personal entries insert `/name`, or `/personal/name` when the name collides with a workspace skill or the chat's pinned context has not resolved yet; workspace entries insert `/workspace/name`. Qualified aliases stay searchable even when the displayed trigger is bare. Before a chat binds a workspace (new chat form, or a selected but unbound workspace), the menu lists personal skills only. Sending a message invalidates the chat detail query, and chatd broadcasts a context watch event when a first-turn bind pins the chat, so the menu picks up newly pinned context without a reload. Makes `UpdateChatWorkspaceBinding` a no-op when the requested workspace/build/agent binding is unchanged, preserving `updated_at` so chat list ordering and watch events stay stable. Includes regression coverage for the no-op binding guard, pinned-context skill mapping, collision qualification, and skills menu behavior. Refs [CODAGT-474](https://linear.app/codercom/issue/CODAGT-474/ux-improvements-for-coder-agents) (skills autocompleting in the editor). |
||
|
|
36e36e2048 |
fix(site): wrap workspace topbar controls on narrow viewports (#27313)
On mobile-width viewports the workspace page grew to ~1080px wide (390px viewport), pushing the schedule controls, status indicator, and action buttons off-screen. Users had to zoom out or scroll horizontally to reach Stop/Restart/Favorite/Share. The topbar header and the right-side controls group used non-wrapping flex rows, and every child is a `whitespace-nowrap` button, so the row's minimum width (~725px for the controls alone) forced the document wider than the viewport. ## Changes - `WorkspaceTopbar`: allow the topbar header and the right controls group to wrap; right controls stay right-aligned when they wrap onto their own row. - `WorkspaceActions`: allow the button row to wrap. - `TopbarData`: merge a caller-provided `className` (no existing caller passed one); the workspace breadcrumbs use it to wrap on very narrow screens. ## Verification Compared before/after with agent-browser on Storybook stories (`Workspace: Running`, `WorkspaceTopbar: Outdated / WithQuotaWithOrgs / Dormant / ConnectedWithMaxDeadline`): | Viewport | Before `scrollWidth` | After `scrollWidth` | |---|---|---| | 320 | 1080 (overflow) | 305 (fits) | | 390 | 1080 (overflow) | 375 (fits) | | 768 | 1080 (overflow) | 753 (fits) | | 1024 | 1080 (overflow) | 1009 (fits) | | 1440 | 1425 (fits) | 1425, pixel-identical (0% diff) | At widths >= 1280 the layout is unchanged (0% pixel diff at 1440 across the stories above). Between ~1080-1230px the controls now wrap onto a second right-aligned row instead of squeezing label text onto two lines inside a single row. Validation: `biome check`, `tsc --noEmit`, and `pnpm test:storybook` for `Workspace.stories.tsx` + `WorkspaceTopbar.stories.tsx` (36 passed). > This PR was prepared by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
1ac106255b | feat: add Anthropic 1M context window toggle for Agents model configs (#27257) | ||
|
|
2ac2295b1e |
fix: do not send or use stale init dynamic parameter state (#27283)
In summary, we use the init message if we have no autofill params. If we do, then we ignore the init message, send another message with the autofilled values, and then when we get *that* response, finally we render the form since we know we have good state. This eliminates the possibility of temporarily rendering with stale state. This is the same fix that was applied to the edit page, but on the create page this time. The only difference is that the create page does not need to wait on a build parameters query, instead it has to wait on the first message from the socket (to get defaults). This also makes one change where we would send the defaults in the init message. The server already knows the defaults so there is no need to send them. The advantage here is that we no longer need to wait for the first message, and it also fixes an issue where fields with blank values were getting validation errors because they were not filled out, before the user had a chance to actually fill them out. |
||
|
|
1453b4b1fc |
docs: document Bedrock mantle protocol (#27296)
Implements: https://linear.app/codercom/issue/AIGOV-518/add-docs-for-bedrock-mantle Follow-up to: https://github.com/coder/coder/pull/26745 |
||
|
|
3dd9265fa6 |
feat: add UI option to disconnect OAuth2 MCP credentials (#27299)
Closes [CODAGT-804](https://linear.app/codercom/issue/CODAGT-804/add-ui-option-to-revoke-oauth-mcp-credentials). Users could authenticate with an OAuth2 MCP server from the chat input, but there was no UI to disconnect those per-user credentials. The backend endpoint (`DELETE /api/experimental/mcp/servers/{id}/oauth2/disconnect`) already existed. ## Changes - Connected OAuth2 MCP rows in the chat input plus menu now show a disconnect icon button next to the enable switch. It opens a confirmation dialog; confirming calls the disconnect endpoint, shows a toast, and refetches MCP configs so the row reverts to the `Auth` button without a reload. - New `disconnectMCPServerOAuth2` API client method and react-query mutation that invalidates `mcp-server-configs`. - Storybook interaction tests: control visibility per auth state, cancel makes no API call, confirm calls the endpoint once, failed disconnect keeps the dialog open. - Hardened `TestMCPServerConfigsOAuth2Disconnect`: seeded tokens flip `auth_connected`, disconnect only removes the calling user's token, and repeat disconnect stays idempotent. The endpoint removes the token stored in Coder; it does not revoke the upstream OAuth grant, so the UI copy says "disconnect" rather than "revoke". Validated with the targeted Go test, Storybook tests (51 passed), tsc, biome, the react-compiler check, and a manual dogfood run (seeded token, disconnect/cancel/reconnect flows verified in the UI). > This PR was authored by Mux, an AI coding agent, on Mike's behalf. |