## Summary
Adds a `--no-build` flag to `coder state push` that updates the
Terraform state directly without triggering a workspace build.
## Use Case
This enables state-only migrations, such as migrating Kubernetes
resources from deprecated types (e.g., `kubernetes_config_map`) to
versioned types (e.g., `kubernetes_config_map_v1`):
```bash
coder state pull my-workspace > state.json
terraform init
terraform state rm -state=state.json kubernetes_config_map.example
terraform import -state=state.json kubernetes_config_map_v1.example default/example
coder state push --no-build my-workspace state.json
```
## Changes
- Add `PUT /api/v2/workspacebuilds/{id}/state` endpoint to update state
without triggering a build
- Add `UpdateWorkspaceBuildState` SDK method
- Add `--no-build`/`-n` flag to `coder state push`
- Add confirmation prompt (can be skipped with `--yes`/`-y`) since this
is a potentially dangerous operation
- Add test for `--no-build` functionality
Fixes#21336
- Fix to display apps with disabled health status on workspaces list
- Migrate WorkspacesPage jest test into vitest
- Modularize vitest setup into separate files:
- setup/polyfills.ts: Blob, ResizeObserver polyfills
- setup/domStubs.ts: Radix UI pointer capture stubs
- setup/mocks.ts: useProxyLatency mock
- setup/msw.ts: MSW server lifecycle
Fixed#20319
**This is just the protobuf changes for the PR https://github.com/coder/coder/pull/21398**
Moved `UploadFileRequest` from `provisionerd.proto` -> `provisioner.proto`.
Renamed to `FileUpload` because it is now bi-directional.
This **is backwards compatible**. I tested it to confirm the payloads are identical. Types were just renamed and moved around.
```golang
func TestTypeUpgrade(t *testing.T) {
t.Parallel()
x := &proto2.UploadFileRequest{
Type: &proto2.UploadFileRequest_ChunkPiece{
ChunkPiece: &proto.ChunkPiece{
Data: []byte("Hello World!"),
FullDataHash: []byte("Foobar"),
PieceIndex: 42,
},
},
}
data, err := protobuf.Marshal(x)
require.NoError(t, err)
// Exactly the same output
// EhgKDEhlbGxvIFdvcmxkIRIGRm9vYmFyGCo= on `main`
// EhgKDEhlbGxvIFdvcmxkIRIGRm9vYmFyGCo= on this branch
fmt.Println(base64.StdEncoding.EncodeToString(data))
}
```
# What this does
This allows provisioner daemons to download files from `coderd`'s `files` table. This is used to send over cached module files and prevent the need of downloading these modules on each workspace build.
Fixes all our Go file imports to match the preferred spec that we've _mostly_ been using. For example:
```
import (
"context"
"time"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/xerrors"
"gopkg.in/natefinch/lumberjack.v2"
"cdr.dev/slog/v3"
"github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/serpent"
)
```
3 groups: standard library, 3rd partly libs, Coder libs.
This PR makes the change across the codebase. The PR in the stack above modifies our formatting to maintain this state of affairs, and is a separate PR so it's possible to review that one in detail.
The pause icon (`||`) for the Stop button was confusing as it suggests
pause/resume functionality. Changed to a square icon (`□`) which is the
standard icon for stop in media players and interfaces.
### Before
<img width="100" alt="before"
src="https://github.com/user-attachments/assets/77e2fee5-cb66-4b47-9a2a-0dccce5c28ca"
/>
### After
The button will now display a square (⬛) stop icon instead of the pause
(⏸) icon.
---------
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
Co-authored-by: Jaayden Halko <jaayden@coder.com>
Upgrades to slog v3 which includes a small, but backward incompatible API change to the acceptible call arguments when logging. This change allows us to verify via compile time type checking that arguments are correct and won't cause a panic, as was possible in slog v1, which this replaces (v2 was tagged but never used in coder/coder).
It also updates dependencies that also use slog and were updated.
I've left the `aibridge` dependency as a commit SHA, under the assumption that the team there (cc @pawbana @dannykopping ) will tag and update the dependency soon and on their own schedule.
Other dependencies, I pushed new tags.
Related to #21320
This pull-request ensures that all the icons are now `256px * 256px` so
that they're standardised across all rendering situations.
| Previous | Now |
| --- | --- |
| <img width="886" height="1652" alt="CleanShot 2025-12-21 at 12 25
03@2x"
src="https://github.com/user-attachments/assets/c298325c-4419-485b-97e2-bb54e6ccc8c0"
/> | <img width="962" height="980" alt="CleanShot 2025-12-21 at 12 26
35@2x"
src="https://github.com/user-attachments/assets/c9cef5ee-115d-4318-8e12-188ea79cc88b"
/> |
* All `*.svg` files are now `256px * 256px` and..
* Added a `do.svg` file.
* Added a `ruby.svg` file.
* Added a `gcp.svg` file.
* All `*.png` files are now `256px * 256px` and..
* Updated the `aws.png` file to match `aws.svg` (deprecated).
* Updated the `azure.png` file to match `azure.svg` (deprecated).
* Updated the `docker.png` file to match `docker.svg` (deprecated).
* Updated the `do.png` file to fill the full `256px` width.
* Deprecated the `do.png`.
* Deprecated the `ruby.png`.
* Deprecated the `gcp.png`.
Closes#21301
This pull-request adds a very simple `function formatDate(date: Date,
options: Intl.DateTimeFormatOptions)` function which will allow us to
standardise the rendering of dates across the application. This is
inline with the content of #21252.
Closes#21260
Pagination buttons could overflow their container on narrower pages
(e.g. audit / logs) because the page button was effectively fixed-width.
This updates the pagination button styling to allow it to expand with
its content (`min-w-8 w-auto`), preventing overflow while keeping the
same icon-button look.
| Previously | Now |
| --- | --- |
| <img width="451" height="118" alt="pagination-old-treatment"
src="https://github.com/user-attachments/assets/ae77e604-89fb-4dc3-9233-d103494e1906"
/> | <img width="451" height="118" alt="pagination-new-treatment"
src="https://github.com/user-attachments/assets/5a948d8a-4643-4eff-95b9-4c2852850447"
/> |
Because this affects more than just the template insights
page (specifically it also affects the deployment stats endpoint which
is shown on bottom bar and Prometheus), the group is being renamed
generically to just "stats collection". In the future if we need to
affect the other stats we can put those options here.
Then, because this change only affects a portion of stats, specifically
usage stats like connection and application time, bytes sent, etc, add a
new sub-group called "usage stats".
Then finally add back the "enable" flag. This also gives us a place to
one day place an "anonymize" flag if we need to go that route.
Closes#21320
This PR introduces a list of deprecated icons that should no longer be displayed in the UI. These icons are kept for backward compatibility but are now filtered out from:
1. The emoji picker component
2. The icons page listing
The deprecated icons include:
- Duplicate icons that have better alternatives (e.g., `apple-grey.svg` → `apple-black.svg`)
- PNG versions of icons that already have SVG versions (e.g., `aws.png` → `aws.svg`)
- Monochrome variants that are no longer needed (e.g., `docker-white.svg`)
## Description
Adds the core AI Bridge MITM proxy daemon. This proxy intercepts HTTPS traffic, decrypts it using a configured CA certificate, and forwards requests to AIBridge for processing.
## Changes
* Added `aibridgeproxyd` package with the core proxy server implementation
* Added configuration options: `CODER_AIBRIDGE_PROXY_ENABLED`, `CODER_AIBRIDGE_PROXY_LISTEN_ADDR`, `CODER_AIBRIDGE_PROXY_CERT_FILE`, `CODER_AIBRIDGE_PROXY_KEY_FILE`
* Added tests for server initialization and MITM functionality
Closes https://github.com/coder/internal/issues/1180
Delete builds were not deleting resources as the tf state being sent in the apply request was empty.
State removed from apply request and read from the session instead.
Relates to #20925
This PR modifies TaskPage to update an outdated workspace instead of
starting it. Before, starting an outdated workspace where the template
required the active version would fail with the error "cannot use
non-active version: rbac: forbidden".
For the case of a dormant workspace, I deemed it safe enough to simply
unset dormancy on an attempted start (ref:
https://github.com/coder/coder/pull/21306). However, automatically
updating a workspace is a more risky option, so I instead elected to
give the user the option of updating their workspace using the existing
tooltip.
**Note:** I made a change to the `WorkspaceOutdatedTooltip` components
to allow it to have children so that the tooltip could trigger over a
wider element instead of just the info icon.
```
<🤖 AI Disclaimer>I got some help from Gemini 3 Flash in "Ask" mode.</🤖 AI Disclaimer>
```
Closes#21052 and is related to #21218
This pull request implements a bunch of changes the team requested to
improve the overall user experience when navigating to the Request Logs
page. Since these are mostly UI changes, screenshots do a much better
job of showing what's different than me trying to explain everything in
words, so I've included them below.
> [!WARNING]
> More globally we've changed how we're rendering `<PaginationHeader
/>`, therefore we've renamed it to `<PaginationAmount />`. This will
effect multiple layouts however its a global improvement we're
intentionally looking to make.
### Preview

### Changes
1. Date formatting set to a standardised way including the month as a
`MMM` (i.e `Dec`)
2. Names and avatars are now rendered larger, furthermore they render
the `.name` field falling back on `.username`.
3. Font-size increased from `text-xs` to `text-sm` to increase overall
legibility globally.
4. Initiator is now rendered inside of a `<Badge />` and gives longer
names a chance to render.
5. Models are now rendered in a `<Badge />` alongside their icons.
6. Input/Output tokens are in a shared `<Badge />`-group alongside
truncation (when necessary).
7. Badge from `5` is rendered with the proper name being visible on
hover (for use if truncated).
8. Move globally the `Showing X of X` counts to the bottom of the tables
(effects other components outside of AI Bridge).
9. Icons are now included within the dropdown for the `Provider` filter.
10. Truncation of elements is now handled so larger prompts don't cause
the table to require further scrolling.
11. New merged Input/Output `<dt>` element with the badge
| Position | Pull-request |
| -------- | ------------ |
| ✅ | [fix: improve AI Bridge request logs
UI/UX](https://github.com/coder/coder/pull/21252) |
| | [feat: add AI Bridge request logs model
filter](https://github.com/coder/coder/pull/21259) |
| | [chore!: promote AIBridge from
`ExperimentalHandler`](https://github.com/coder/coder/pull/21278) |
| | [feat: implement request log collapsing prompt (`<RequestLogsPrompt
/>`)](https://github.com/coder/coder/pull/21313) |
---------
Co-authored-by: ケイラ <mckayla@hey.com>
This PR separate the data retrieval for workspace sharing ACL into a
custom hook and creates a separate form component. This is in
preparation for reusing the workspace sharing form from a new share
button on the workspace page.
Closes#21217
This pull-request traverses the `token_usages.metadata[...]` fields and
merges them into a single consumable object so that we're able discern
information about the metadata within the token usages at a glance. Its
not the be-all end-all implementation of this feature but its a stepping
stone in order to render more useful data to the frontend.
These are currently mergable because they only contain `number` based
fields. When it encounters something within the object that can't be
merged (minus empty objects `{}`) it will simply return them as an
array.
### Preview
<img width="2682" height="1360" alt="CleanShot 2025-11-28 at 15 30
09@2x"
src="https://github.com/user-attachments/assets/e07e6515-4b8e-4169-841c-38fd83c434f9"
/>
### Logic breakdown
<img width="914" height="1016" alt="CleanShot 2025-11-28 at 15 11 13@2x"
src="https://github.com/user-attachments/assets/34b78fe1-3b58-4b78-a552-028ea5a88dc4"
/>
This removes the deprecated AITaskPromptParameterName constant and all
backward compatibility code that was added for v2.28.
- Remove AITaskPromptParameterName constant from codersdk/aitasks.go
- Remove backward compatibility code in coderd/aitasks.go that populated
the "AI Prompt" parameter for templates that defined it
- Remove the backward compatibility test (OK AIPromptBackCompat)
- Update dbfake to no longer set the AI Prompt parameter
- Remove AITaskPromptParameterName from frontend TypeScript types
- Remove preset prompt read-only feature from TaskPrompt component
- Update docs to reflect that pre-2.28 definition is no longer supported
Task prompts are now exclusively stored in the tasks.prompt database
column, as introduced in the migration that added the tasks table.
**Breaking Change:** Existing oauth apps might now use PKCE. If an
unknown IdP type was being used, and it does not support PKCE, it will
break.
To fix, set the PKCE methods on the external auth to `none`
```
export CODER_EXTERNAL_AUTH_1_PKCE_METHODS=none
```
Provisioner steps broken into smaller granular actions.
Changes:
- `ExtractArchive` moved to `init` request (was in `configure`)
- Writing `tfstate` moved to `plan` (was in `configure`)
- Moved most plan/apply outputs to `GraphComplete`
closes: https://github.com/coder/internal/issues/858
Similar to https://github.com/coder/coder/pull/19375, this one uses
system permissions for fetching actual user and group data.
Modifies the `workspaces_expanded` view to fetch the required data; this way it's made available to all code paths that make use of it.
Also fixes a bug in a test helper function that can result in `null` being saved to the DB for `user_acl` or `group_acl` and break tests; a defensive check constraint that prevents this is worth a PR, e.g:
`ALTER TABLE workspaces
ADD CONSTRAINT group_acl_is_object CHECK (jsonb_typeof(group_acl) = 'object');`
Also adds missing `OwnerName` in `ConvertWorkspaceRows`.
closes#19974
This PR replaces all remaining MUI tooltips with our shadcn tooltip
component, and uncomments the linter restriction on importing the MUI
tooltip
Closes#20399
To summarize the original commit messages:
- Do not log stats to the database.
- Return errors on the insight endpoints.
- Update the frontend to show those errors.
- Also fixes an issue with getting the user status count via codersdk,
since I added a test to ensure it was not disabled by this flag and it
was sending the wrong payload.
for #19974
`ShareIcon`, which returns a MUI tooltip, had these problems:
1. There was no Storybook story which rendered the "Open external URL"
tooltip
2. `AppLink` renders a button. If it has tooltip text, this button is
also a Radix `TooltipTrigger`. Since `ShareIcon` is rendered as a child
of the `AppLink` button, `ShareIcon`'s tooltip (a nested tooltip) was
never appearing. I did try turning `ShareIcon` into a Radix tooltip as
well, but I still couldn't get the nested tooltip's text to appear, and
nested tooltips are not very accessible. AFAIK there's no way to focus a
child element of a button.
I've deleted the separate `ShareIcon` component and moved `ShareIcon`'s
tooltip text to the bottom of `AppLink`'s tooltip:
## before
<img width="175" height="121" alt="image"
src="https://github.com/user-attachments/assets/ad17927e-c3d1-499b-83f8-a5832b777305"
/>
^The `UsersIcon` on the right is a MUI tooltip trigger, but it can't
receive focus. It's supposed to show the text "Shared with all
authenticated users" when focused
## after
<img width="228" height="121" alt="image"
src="https://github.com/user-attachments/assets/adc202c1-57cd-4a80-8f94-f7f32897d286"
/>
for #19974
The MUI tooltip inside `PaginationNavButton` was a controlled component.
This + the stateful logic inside `PaginationNavButtonCore` meant that
`showDisabledMessage` would never be set to true. I.e., the "You are
already on the first page" tooltip if on the first page and the "You are
already on the last page" tooltip if on the last page would never show
up.
The `PaginationNavButton`s gets disabled if we're at either the
first/last page, and disabled buttons can't receive focus, so there's no
way to open the MUI tooltips with keyboard navigation.
Removing the MUI tooltip + related props from `PaginationNavButton` has
no effect on my screen reader UX with macOS VoiceOver; it's entirely
unchanged
## Summary
This adds configurable overload protection to the AI Bridge daemon to
prevent the server from being overwhelmed during periods of high load.
Partially addresses coder/internal#1153 (rate limits and concurrency
control; circuit breakers are deferred to a follow-up).
## New Configuration Options
| Option | Environment Variable | Description | Default |
|--------|---------------------|-------------|---------|
| `--aibridge-max-concurrency` | `CODER_AIBRIDGE_MAX_CONCURRENCY` |
Maximum number of concurrent AI Bridge requests. Set to 0 to disable
(unlimited). | `0` |
| `--aibridge-rate-limit` | `CODER_AIBRIDGE_RATE_LIMIT` | Maximum number
of AI Bridge requests per second. Set to 0 to disable rate limiting. |
`0` |
## Behavior
When limits are exceeded:
- **Concurrency limit**: Returns HTTP `503 Service Unavailable` with
message "AI Bridge is currently at capacity. Please try again later."
- **Rate limit**: Returns HTTP `429 Too Many Requests` with
`Retry-After` header.
Both protections are optional and disabled by default (0 values).
## Implementation
The overload protection is implemented as reusable middleware in
`coderd/httpmw/ratelimit.go`:
1. **`RateLimitByAuthToken`**: Per-user rate limiting that uses
`APITokenFromRequest` to extract the authentication token, with fallback
to `X-Api-Key` header for AI provider compatibility (e.g., Anthropic).
Falls back to IP-based rate limiting if no token is present. Includes
`Retry-After` header for backpressure signaling.
2. **`ConcurrencyLimit`**: Uses an atomic counter to track in-flight
requests and reject when at capacity.
The middleware is applied in `enterprise/coderd/aibridge.go` via
`r.Group` in the following order:
1. Concurrency check (faster rejection for load shedding)
2. Rate limit check
**Note**: Rate limiting currently applies to all AI Bridge requests,
including pass-through requests. Ideally only actual interceptions
should count, but this would require changes in the aibridge library.
## Testing
Added comprehensive tests for:
- Rate limiting by auth token (Bearer token, X-Api-Key, no token
fallback to IP)
- Different tokens not rate limited against each other
- Disabled when limit is zero
- Retry-After header is set on 429 responses
- Concurrency limiting (allows within limit, rejects over limit,
disabled when zero)
Implements cmd+enter (Mac) / ctrl+enter (Windows/Linux) keyboard
shortcut for submitting tasks on the tasks page. Regular enter key still
creates new lines as expected.
Fixes#21179🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Added specific icons for common file types in the template file tree:
- **.sh files**: TerminalIcon (terminal/shell scripts)
- **.json files**: BracesIcon (JSON data files)
- **.yaml/.yml files**: FileCodeIcon (YAML configuration files)
<img width="260" height="290" alt="image"
src="https://github.com/user-attachments/assets/a470f4bc-fc2c-4e2d-8067-a9fbbfe32e42"
/>
These icons help users quickly identify file types at a glance in the
template editor.