Commit Graph
5542 Commits
Author SHA1 Message Date
Andrew Aquino 023a1c992c fix(site): truncate devcontainer name with ellipsis at all screen sizes (#26359)
ref DEVEX-449

## before

In `AgentDevcontainerCard`, the devcontainer's display name truncated
with an ellipsis--but only when the viewport is <768px (parent has
`md:w-full`), which is also when the display name width gets capped at
320px (`max-w-xs`). At larger screen sizes, the display name overlaps
with the rebuild button to the right.


https://github.com/user-attachments/assets/47af30a2-f446-4b5f-bf63-24afb0532b19

## after

Now, the devcontainer display name fills up as much width as possible at
all screen sizes (not just >=768px), and it also gets truncated with an
ellipsis at all screen sizes.


https://github.com/user-attachments/assets/68579438-6fb5-40ea-93cf-c3814dfaac1a

---

(If we have a way to automate resizing screens in Storybook, lmk!)

The trick is to set a `min-width` on the text we want to truncate, see
this CSS Tricks article: https://css-tricks.com/flexbox-truncated-text/

I changed `max-w-xs` to `min-w-[284px]`. In addition to constraining the
display name's width (see "before" above), the `max-width` caused the
rebuild button to wrap to the next line if the screen is too narrow to
show the display name at that width. This behavior on small screens is
preserved. 🙂 However, since the display name's width isn't constrained
anymore, it's written out fully if possible, which causes the rebuild
button to wrap lines on wider screens if the display name is very long.
2026-06-18 09:15:33 -07:00
Atif Ali 0f4a3df2c6 fix: respect automatic_updates policy when building workspace action list (#26362) 2026-06-18 19:57:55 +05:00
Jeremy RuppelandAndrew Aquino dca8178f8d feat(site): add ModuleSelectStep (#26427)
Implement the module selection wizard step with multi-select toggle and
conflict warnings.

- Add `getTemplateBuilderModules` API client method with optional `base`
parameter for OS filtering
- Add react-query wrapper with `staleTime: Infinity` to prevent
re-fetches on step navigation
- Render a flat grid of `ModuleCard` components with checkbox-style
multi-select
- Show non-blocking conflict warnings when selected modules declare
`conflicts_with` each other
- Map selections to `TemplateBuilderComposeModule[]` and
`SelectedModuleMeta[]` for wizard state

Relates to [DEVEX-285](https://linear.app/codercom/issue/DEVEX-285).

> [!NOTE]
> This PR was authored with Coder Agents.

---------

Co-authored-by: Andrew Aquino <dawneraq@gmail.com>
2026-06-18 09:42:03 -04:00
Jeremy Ruppel 1546a0a58f feat: add BaseTemplateParametersStep (#26426)
Implement the base template parameters wizard step, which renders a
configuration form for base template variables using the existing
`TemplateConfiguration` and `ConfigurationField` components.

- Map `TemplateBuilderModuleVariable` to `ConfigurationFieldDefinition`
(switch for bool, text input for string/number)
- Read variable definitions from the cached bases query
- Disable Continue button until all required non-sensitive variables
have values (`baseParametersComplete` helper)
- Step is automatically skipped when the selected base has no parameters
(e.g. Docker)
- Update `toComposeRequest` to include `base_variable_values` in the API
payload

Relates to [DEVEX-284](https://linear.app/codercom/issue/DEVEX-284).

> [!NOTE]
> This PR was authored with Coder Agents.
2026-06-17 14:56:52 -04:00
Jeremy Ruppel 87de6dc23e feat: add base template variables to API (#26425) 2026-06-17 12:22:35 -04:00
Nick VigilanteandCoder 6c95a618b4 fix: replace stale docs() paths with redirect destinations (DOCS-253) (#25740)
## Summary

Replaces 9 stale docs paths and 2 stale doc anchors in `site/src/`, and
adds a TS/TSX audit script (`site/scripts/audit-docs-paths.mjs`) plus
unit tests that scan the codebase for paths that resolve via
`coder.com/redirects.json`.

### Redirect-target updates (9)

Each of these paths' `/docs/...` source matches a Next.js redirect rule,
so requests today produce a 302 on `coder.com`. The audit script
identifies them by cross-referencing against `redirects.json`.

- Five update product-code references to `/ai-coder/ai-bridge` (renamed
to `/ai-coder/ai-gateway` in v2.33).
- One updates a commented-out reference to
`/templates#template-filtering` in `TemplatesFilter.tsx`.
- Three update notification-template mock data in
`testHelpers/entities.ts` that pointed at the renamed
`/docs/templates/schedule`.

### Anchor-only updates (2)

These paths are still live on `coder.com` (no redirect), but their
`#fragment` no longer matches a heading on the destination page.
Fragments are evaluated client-side and never sent to the server, so the
audit script does not catch them. Found and verified manually against
the current docs.

- `AuditFilter.tsx`: `/admin/security/audit-logs#filtering-logs` →
`/admin/security/audit-logs#how-to-filter-audit-logs`. The current
heading is `## How to Filter Audit Logs` in
[`docs/admin/security/audit-logs.md`](https://github.com/coder/coder/blob/main/docs/admin/security/audit-logs.md).
- `UserAuthSettingsPageView.tsx`: drops the stale `#openid-connect`
anchor; the path itself (`/admin/users/oidc-auth`) is unchanged. The
page H1 is now `# OpenID Connect`, so the bare path lands at the same
place the anchor used to.

None are user-visible label changes; only the doc target URLs change.

## Audit script

`site/scripts/audit-docs-paths.mjs` cross-references TS/TSX docs-URL
references against `coder.com/redirects.json` and reports anything that
resolves via a redirect (which means stale source). It catches four
forms:

- `docs("/...")` / `docs('/...')` / `` docs(`/...`) ``
- `` docs(`/.../${expr}/...`) `` (literal prefix, flagged as dynamic)
- `"https://coder.com/docs/..."` and other quoted forms
- `](https://coder.com/docs/...)` and `](/docs/...)` markdown-link forms

The full audit (26 findings: 9 in `coder/coder/site/`, 17 in
`coder/coder.com/src/`) lives in [DOCS-253 on
Linear](https://linear.app/codercom/issue/DOCS-253) rather than being
committed to the repo. Re-run locally with:

```bash
node site/scripts/audit-docs-paths.mjs \
  --redirects=/path/to/coder.com/redirects.json \
  --roots=/path/to/coder/site/src,/path/to/coder.com/src
```

Default output goes to `docs/.audit/redirects-audit-YYYY-MM-DD.md`,
which is gitignored.

## Tests

`site/scripts/audit-docs-paths.test.mjs` has 59 cases covering the four
regexes, `matchRedirect` (exact, `:path*`, `:slug(.*)`, miss),
`findMatchingRedirect`, `stripQueryAndFragment`, `literalPrefix`,
`extractReferences` end-to-end with line numbers and multi-line `docs()`
calls, `buildReport` (empty input, repo grouping and sort order,
fragment annotation, unclassified section), `walk` against a real temp
filesystem (recursion, extension filter, `SKIP_DIRS` pruning,
missing/file inputs, seeded results), and `runCli` (missing-root
warning, real-but-empty root). Run with `pnpm exec vitest run
scripts/audit-docs-paths.test.mjs --project=unit` from `site/`.

## Notes

- User-visible "AI Bridge" label text is not changed here. Renaming the
product surface from "AI Bridge" to "AI Gateway" is tracked separately
by the AI Governance team in AIGOV-233.
- A vitest assertion that no literal path in `site/src/` resolves via a
redirect will land in a follow-up PR (DOCS-257), so future drift fails
fast in CI.
- A generated `DocsPath` type for the `docs()` helper is planned in
DOCS-254.
- The `/docs/templates/schedule` drift in `entities.ts` also appears in
`coderd/notifications/testdata/*.golden` test fixtures and in historical
SQL migrations under `coderd/database/migrations/`. Those are tracked
under DOCS-256 (A2: non-TS audit) and not in scope here.

## Related work

- Linear: DOCS-253 (this PR), parent DOCS-209.
- Companion redirect rule on the coder.com side: coder/coder.com#826.
- Companion fixes for the 17 coder.com findings: coder/coder.com#876
(supersedes the closed coder/coder.com#827, which was made redundant by
coder/coder.com#832).

<details>
<summary>Implementation plan (Linear DOCS-209)</summary>

| Phase | Scope | Linear | Status |
|---|---|---|---|
| D | Versioned redirect for `/docs/@v2.33.x/ai-coder/ai-bridge` in
`coder.com/redirects.json` | DOCS-255 | coder/coder.com#826 open |
| A1 | TS/TSX audit + autofix in `coder/coder/site/` | DOCS-253 | This
PR |
| A1 follow-up | Same autofix in `coder/coder.com/src/` (3 remaining
findings after coder/coder.com#832) | DOCS-281 | coder/coder.com#876
open |
| A2 | Non-TS audit in `coder/coder` (Go, comments, markdown) | DOCS-256
| Backlog |
| A3 | code-server audit | DOCS-252 | Backlog |
| B | vitest assertion against `redirects.json` | DOCS-257 | Blocked by
A1 |
| C | Generated `DocsPath` type | DOCS-254 | Blocked by B |

</details>

---

Generated by Coder Agent on behalf of @nickvigilante.

---------

Co-authored-by: Coder <coder@users.noreply.github.com>
2026-06-17 12:19:08 -04:00
Jeremy Ruppel 286bd836f4 feat(site): add BaseInfraSelectStep (#26424)
Implement the first wizard step for selecting a base infrastructure
template.

- Add `getTemplateBuilderBases` API client method and react-query
wrapper
- Render a responsive grid of `TemplateCard` components fetched from
`GET /api/v2/templatebuilder/bases`
- Map `TemplateBuilderBase` to `SelectedBaseMeta` with `hasParameters`
derived from the base variables
- Single-choice selection that dispatches `SET_BASE` to wizard state,
preserving selection on back navigation

Relates to [DEVEX-283](https://linear.app/codercom/issue/DEVEX-283).

> [!NOTE]
> This PR was authored with Coder Agents.
2026-06-17 11:51:04 -04:00
Steven Masley be25ba24b0 fix: disable custom roles as possible default org roles (#26461) 2026-06-17 09:15:21 -05:00
Danielle Maywood e6147d082a refactor(site): share chat model/provider test factories (#26408) 2026-06-17 14:35:13 +01:00
Danielle Maywood 8d725969bf chore!: remove coder agents insights page (#26457)
Removes the coder agents PR Insights page (`/agents/settings/insights`) and all of its backend support. The page had previously been hidden and was only reachable via deep link. It had previously been hidden due to the dubious value provided in the current iteration.
2026-06-17 14:02:19 +01:00
Ehab Younes 74a7ad0929 feat: add group AI budget management UI (#26375)
Add an AI budget section to the group settings page, gated by the
aibridge feature and the ai-gateway-cost-control experiment. Saves a
per-member monthly budget via the group AI budget endpoints alongside
the group patch: empty is uncapped (deletes the budget), 0 disables,
and any value >= 0 is accepted.

Closes AIGOV-294
2026-06-17 13:22:18 +03:00
Danielle Maywood cf0c9ce16b fix(site/src/pages/AgentsPage): preserve chat input typed while loading (#26415) 2026-06-17 09:58:34 +01:00
Ethan d638b1aaed chore: gate Coder Agents app and port tabs behind experiment (#26395)
The workspace-app and port preview tabs in the Coder Agents right panel
were previously gated behind a `devel` prerelease build check, which
can't be toggled in real deployments.

This replaces that check with a proper `agent-app-tabs` deployment
experiment, registered in `ExperimentsKnown`, so the feature can be
enabled via `CODER_EXPERIMENTS=agent-app-tabs` like any other
experiment. The frontend now reads
`experiments.includes("agent-app-tabs")` from the dashboard instead of
`getPrereleaseFlag(buildInfo) === "devel"`.

Depends on #26208
2026-06-17 17:29:20 +10:00
Ethan 5ee1946b67 feat: add right panel tabs for workspace apps and ports (#26208)
Adds workspace app and forwarded port tabs to the AgentsPage right panel, so app previews and port views can sit alongside terminals while working in the chat view.

- The new add-tab dropdown lists the agent's apps and a ports submenu: embeddable apps open as iframe tabs, command apps open as renamed terminal tabs running their command, and ports open in a new port preview panel served through the wildcard access URL.
- Tabs persist per chat and are validated against the current workspace state: tabs whose app disappears, stops being embeddable, or whose agent no longer exposes the port forwarding helper are hidden rather than deleted, and reappear if the workspace exposes them again.
- A shared `usePortsData` hook keeps the add-tab control, workspace pill, and existing `PortForwardButton` on the same port queries and refresh cadence.
- ~~App and port tabs are limited to `devel` builds for now; terminal tabs remain generally available. This was done in favour of adding a backend experiment for a frontend-only feature.~~ TODO: I'm just gonna switch to a backend experiment.

Closes CODAGT-346
2026-06-17 13:59:21 +10:00
Asher 744c00f45c fix: handle blank dynamic parameter values consistently (#26122)
There was inconsistency with what the form showed and what actually was
sent to the backend. I opted to make it so that explicitly blank values
are always sent rather than have blank values silently changing to the
default value.
2026-06-16 15:05:27 -08:00
McKayla はな 3e68dd304a ci: set up pixel (#26324)
IT'S FINALLY HERE
2026-06-16 14:43:54 -06:00
Jeremy Ruppel 0fc25d38ce feat(site): add wizard shell, step registry, and feature flag gate (#26423)
Add the template builder wizard route at `/templates/new/builder` with
feature flag gating, step navigation, and wizard state management.

- Read `template_builder.disabled` from deployment config and redirect
to `/templates/new` when disabled
- Five-step wizard registry with skip logic for `base-parameters` (no
params) and `module-settings` (no configurable vars)
- Reducer managing base selection, module selection, variable values,
and template customizations with state preservation across navigation
- Two-column layout with step content area, `SelectionSummary` sidebar,
and back/forward navigation
- Page/PageView separation using `Margins`, `PageHeader`, and standard
layout components

Part 1 of the Template Builder stack. Relates to
[DEVEX-282](https://linear.app/codercom/issue/DEVEX-282).

> [!NOTE]
> This PR was authored with Coder Agents.
2026-06-16 16:38:51 -04:00
Steven Masley 0e45ded0ed feat: deployment flag to auto handle changed oidc providers (#26419)
An opt-out flag exists as an escape hatch

closes https://linear.app/codercom/issue/PLAT-343/automatically-reset-user-link-for-affected-users-when-idp-provider
2026-06-16 13:26:04 -07:00
Andrew Aquino b71bc31eec feat: change StepDivider color to green when previous step is completed (#26394)
ref DEVEX-482
2026-06-16 12:00:56 -07:00
Kyle Carberry bca0ce04ca feat: integrate agent context snapshots into chats (#26389)
Makes the chat context foundation from #26385 live. That PR added the
storage columns, writer queries, and a dormant
`agentapi.ContextDirtyMarker` trigger with no production callers; this
PR wires them together end to end.

When a workspace agent pushes a context snapshot, bound chats now
hydrate to that snapshot's hash, and a later push with a different hash
flips already-pinned chats to dirty (emitting a `context_dirty` watch
event after the transaction commits). Chat creation pins the agent's
latest snapshot when one already exists. The experimental chat API
exposes this as `Chat.Context` (`*ChatContext` with `dirty`,
`dirty_since`, `error`), and a new `PUT
/api/experimental/chats/{chat}/context` endpoint re-pins the agent's
latest snapshot and clears the dirty marker.

`context_dirty_resources` stays NULL (the resource-level diff is
deferred to the UI phase) and the live per-turn context pull is
unchanged.

The end-to-end test provisions a workspace agent via the echo
provisioner, connects it over the Agent API v2.10, and exercises the
full path: an initial push hydrates a bound chat (clean), a second push
with a different hash marks it dirty, the API reports the dirty state,
and the refresh endpoint clears it.

<details>
<summary>Decision log</summary>

- **API shape — sub-struct.** Dirty state is surfaced as
`codersdk.Chat.Context *ChatContext { Dirty bool; DirtySince *time.Time;
Error string }` rather than flat fields, matching the RFC's named
`ChatContext` type and leaving room for future fields (resource diff,
sources). `db2sdk.Chat` populates it when the chat is context-tracked
(`len(ContextAggregateHash) > 0`), dirty, or carries a snapshot error,
and leaves it nil (`omitempty`) otherwise. `Dirty` mirrors
`context_dirty_since` being set.
- **Marker wiring.** The chat daemon is injected directly as the
`agentapi.ContextDirtyMarker`. It is unconditionally constructed (only
its background worker is gated), so the marker is always non-nil and the
wiring matches every other `api.chatDaemon` call site. `agentapi` still
treats a nil marker as "chatd absent", so `PushContextState` stays a
pure write path for any future caller that does not wire chatd in.
- **Refresh is atomic.** `RefreshChatContext` reads the agent's latest
snapshot and re-pins the chat in one repeatable-read transaction, so a
concurrent push cannot land between the read and the write and leave the
chat pinned to a stale hash with the dirty marker cleared.
- **Hydrate + dirty run inside the push transaction.** The fan-out
shares the push's transaction so a concurrent refresh cannot interleave
with the version gate; `context_dirty` watch events publish only after
commit. The pinned hash on dirtied chats is intentionally left unchanged
— the refresh endpoint re-pins it.
- **Dirtied chats keep their pinned hash.** Drift is advisory: a dirty
chat stays usable, and refreshing is the only path that advances the
pinned hash.
- **Test binds `chats.agent_id` directly.** In production the binding is
set lazily during a chat turn (`chatd.persistBuildAgentBinding`); the
test sets it via `dbgen` so it exercises the context flow rather than
turn resolution.

Plan: `coderd/x/chatd` context integration + E2E (sub-struct API,
create-time + push-time hydration, refresh endpoint;
`context_dirty_resources` and the per-turn pull untouched).

</details>

🤖 Generated by Coder Agents on behalf of @kylecarbs
2026-06-16 17:46:47 +00:00
Danny Kopping 0c1c4af40a fix(site/src/pages/AISettingsPage): allow Bedrock IAM-role setup (#26400)
The Bedrock create form required both `access_key` and
`access_key_secret`, blocking deployments that authenticate against AWS
through an IAM role, instance profile, or `AWS_PROFILE`. The backend
already accepts a Bedrock provider that is configured by region alone
(see `codersdk.AIProviderBedrockSettings.IsConfigured`), so the UI was
the only thing standing between the operator and a working IAM-role
provider.

The Yup schema now treats both fields as optional while keeping the
cross-validation that forces the pair to travel together. A descriptive
note under the inputs tells the operator that leaving both blank falls
back to ambient AWS credentials, and links to the [Amazon Bedrock
section](https://coder.com/docs/ai-coder/ai-gateway/providers#amazon-bedrock)
of the AI Gateway providers docs for the credential chain and IAM
permissions. The mapping into `CreateAIProviderRequest` already omits
empty credential fields, so the wire payload sends only `region`,
`model`, and `small_fast_model`, which is enough for `IsConfigured()` on
the backend.

The model and small-fast model fields are now pre-filled with the modern
Sonnet 4.5 and Haiku 4.5 IDs from `codersdk.aiGatewayBedrockModel` /
`codersdk.aiGatewayBedrockSmallFastModel`, matching the legacy
environment seed path. A second docs note under those fields points at
the [AWS Bedrock model
cards](https://docs.aws.amazon.com/bedrock/latest/userguide/model-cards.html)
page so operators can find the canonical model IDs without leaving the
form. This also addresses the AIGOV-411 ask.

Adds `providerFormValuesToCreate` coverage for the no-credential and
whitespace-only paths, plus three new `ProviderForm` stories: one that
verifies the model fields pre-fill, one that submits without static
credentials, and one that verifies a half-typed credential pair stays
blocked.

Closes
[CODAGT-626](https://linear.app/codercom/issue/CODAGT-626/bedrock-ui-requires-access-keys-for-iam-role-setup).
Partial coverage for
[AIGOV-411](https://linear.app/codercom/issue/AIGOV-411/ai-gateway-providers-improve-bedrock-model-fields-in-ui)
(model pre-fill plus docs link; combobox, model ID pattern validation,
and docs site updates remain).

> The Slack thread also flagged a separate edit-time regression: "if I
go to edit an existing provider, all the fields I set are not on the
UI." I did not see that reproduce against the masked-credential edit
story, and the issue description focuses on the create flow, so I left
it for a separate investigation rather than bundling it into this fix.

<img width="1169" height="814" alt="image"
src="https://github.com/user-attachments/assets/08741641-da86-4acc-82ac-ef758f739f58"
/>

<sub>This PR was created by a Coder Agent on behalf of
@dannykopping.</sub>
2026-06-16 16:37:45 +02:00
Sas Swart 2716e2181c feat: purge boundary logs past retention (#24815)
Add a periodic purge job for `boundary_logs` rows past their retention
threshold, following the same pattern as the existing audit log and
connection log purge jobs in `dbpurge`.

Expose a `--boundary-log-retention` deployment flag (env
`CODER_BOUNDARY_LOG_RETENTION`, YAML `retention.boundary_logs`). Default
is `0` (keep indefinitely). When set to a positive duration, `purgeTick`
deletes rows where `captured_at` is older than the threshold in batches
of 10,000, matching other log purge operations. The `boundary_logs`
label is added to the `records_purged_total` Prometheus counter.

Also removes the random-UUID fallback for `OwnerID` in
`dbgen.BoundarySession`. The previous fallback generated a UUID that
could never satisfy the `boundary_sessions_owner_id_fkey` FK constraint,
masking test setup bugs. Callers must now provide a valid user ID or
accept NULL (the legitimate "user deleted" state).
2026-06-16 14:32:54 +02:00
Susana Ferreira 12d7ad6100 feat: add ai-gateway-cost-control experiment flag (#26399)
Adds the `ai-gateway-cost-control` experiment flag to gate new cost
control endpoints and upcoming frontend UI behind an explicit opt-in.

Currently AI Gateway cost control supports the following endpoints:
- `GET/PUT/DELETE /api/v2/organizations/{org}/groups/{group}/ai/budget`
- `GET/PUT/DELETE /api/v2/users/{user}/ai/budget`

Note: the group-level endpoints were already released in v2.34.0 and
remain ungated. Only the user-level endpoints are gated behind this
experiment. Future cost control endpoints and UI should use this
experiment for gating until the feature is stable.

> Generated by Coder Agents on behalf of @ssncferreira
2026-06-16 10:33:34 +01:00
Jeremy Ruppel 00a08f35cc revert(site): revert "chore: bump vite from 8.0.10 to 8.0.16 in /site" (#26390)
Reverts coder/coder#26388

Repeat of #26034
2026-06-16 15:28:34 +10:00
Asher b5b80dbe8e fix: do not send or use stale init dynamic parameter state (#26357)
Previously, there could be a gap where the web socket has been connected
and gets the initial message but the build parameters request was still
in flight. This caused two issues:

1. Because we only send initial parameters as a response to a message,
when the message comes first and the build parameters have not resolved
yet, we end up not sending the initial parameters, meaning the form
could be stale until the next edit the user makes.
2. And if the user does make an edit, once we get that response back we
would then send the initial parameters, essentially reverting back to
the initial state since the initial params do not include the user's
edits. So the user would need a second edit to finally sync up.

To resolve both issues, we ignore the web socket's initial message until
we get the build parameters, at which point we decide whether we can use
that initial message (when there are no build params) or if we need to
continue ignoring it and send the initial parameters to get the correct
state then finally render the form.
2026-06-15 16:38:54 -08:00
Jeremy Ruppel de31c7c18e feat: add TemplateBuilderCreateTemplate SDK types and client method (#26360)
Adds `POST /api/v2/templatebuilder/compose/template`, a synchronous
endpoint that composes a template from a base and modules, validates it
via a provisioner import job, and creates the template in a single
request.

The handler composes terraform files, bundles them as a tar, inserts the
file with hash-based dedup, creates a template version with an import
job, waits up to 2 minutes for the job to complete, classifies errors
for known failure modes (network-unreachable registry, DNS failures),
then creates the template on success. Canceled and failed jobs return
appropriate error responses.

Also adds `hclwrite.Format` to composed terraform output for canonical
HCL formatting.

Closes https://linear.app/codercom/issue/DEVEX-279

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

- SDK types and client method in `codersdk/templatebuilder.go` with
validation tags matching the standard template creation path
(`template_display_name`, `lt=128`)
- `ClassifyProvisionerError` in `coderd/templatebuilder/errors.go`
detects DNS, connection refused, i/o timeout, and TLS handshake failures
and returns actionable messages
- `waitForProvisionerJob` polls with a ramp-up interval schedule (100ms,
200ms, 500ms, then 1s steady) and accepts an `onUpdate` callback for
future SSE streaming
- Audit logging for both template and template version creation
- TOCTOU name uniqueness: early check for fast feedback, DB unique
constraint catch for the race window (returns 409, not 500)
- Swagger annotations for all error responses (400, 404, 409, 504)

</details>

> 🤖 Generated by Coder Agents
2026-06-15 18:12:55 -04:00
dependabot[bot] dc79663573 chore: bump vite from 8.0.10 to 8.0.16 in /site (#26388)
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=8.0.10&new-version=8.0.16)](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>
2026-06-15 20:35:15 +00:00
Paweł BanaszewskiandJake Howell e019210f4b feat(site): add AI Gateway keys management page (#25817)
> Vibe-coded using Coder Agents, author with limited frontend knowledge,
manually tested.

Adds an `AI Gateway Keys` page under `Admin settings > AI > AI Gateway
Keys` for key management of keys used by standalone AI Gateway replicas
to authenticate into `coderd`.
The page is shown to users with `viewAIGatewayKeys` permission and a
Premium license with AI Gateway enabled.
Adds Storybook coverage.

---------

Co-authored-by: Jake Howell <jacob@coder.com>
2026-06-15 18:26:58 +02:00
Marcin Tojek c50cef5ae1 fix: add Gemini/Google provider support to AI Bridge session page (#26374)
Fixes https://github.com/coder/internal/issues/1576
2026-06-15 16:27:36 +02:00
Jeremy Ruppel ce21a565dd feat: add TemplateBuilderCompose SDK types and client method (#26350)
> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.

Part 3 of DEVEX-277 (POST /api/v2/templatebuilder/compose).

Adds SDK types and client method for the compose endpoint:

- `TemplateBuilderComposeRequest` with `BaseTemplateID` and `Modules` (list of `{ID, Variables}`). Registry URL is omitted from the request; it comes from server-side deployment config.
- `TemplateBuilderCompose(ctx, req)` client method that POSTs the request and returns raw `application/x-tar` bytes (matching the `Download` pattern in `codersdk/files.go`).
- Generated TypeScript types updated.
2026-06-15 09:29:39 -04:00
Danielle Maywood 2c754630f6 fix(site/src/pages/AgentsPage): separate interactive and display file reference chips (#26094) 2026-06-15 10:01:48 +01:00
Jeremy Ruppel 9a6e348f5d feat: add GET /api/v2/templatebuilder/modules endpoint (#26117)
Implement `GET /api/v2/templatebuilder/modules`, which returns the
filtered list of modules available for a given base template. Reads from
the bundled catalog via `LoadModules()` and applies OS-compatibility
filtering based on the `base` query param.

Computed variables (e.g. `agent_id`) are excluded from the API response
at the `ToSDK()` conversion boundary since they are wired automatically
by the builder. The `Computed` field is removed from the SDK type. Adds
`CompatibleWithOS()` to `ModuleManifest` for OS filtering.

Returns 400 for unknown base IDs and 404 when the template builder is
disabled.

Depends on #26116

> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.
2026-06-12 17:53:48 -04:00
Jeremy Ruppel 776fbfa748 feat: add GET /api/v2/templatebuilder/bases endpoint (#26116)
Implement `GET /api/v2/templatebuilder/bases`, which returns the list of
base templates available in the template builder. Reads from the bundled
catalog by cross-referencing `templatebuilder.BaseTemplateIDs()` with
`examples.List()`, enriching each entry with the OS from the `exampleID
-> OS` map.

The endpoint is gated behind the template builder feature flag (returns
404 when disabled) and requires `policy.ActionRead` on
`rbac.ResourceTemplate`.

Depends on #26115

> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.
2026-06-12 17:40:02 -04:00
TJ d6aa3d61ee fix(site): add alt text to Avatar so workspaces images pass WCAG (#26223)
## Summary

Fixes the WCAG image-alt failures reported on
https://dev.coder.com/workspaces. The audit flagged ~52 `<img>` elements
without an `alt` attribute, all matching the inner `<img>` rendered by
Radix `AvatarPrimitive.Image` inside our `Avatar` component (selectors
like `.size-full.object-contain`, `.size-[--avatar-lg].rounded-[6px]`,
`.size-[--avatar-sm]`). Two `ExternalImage` callsites on the same page
were also missing `alt`.

## Changes

- `Avatar`: add optional `alt?: string` and forward it to
`AvatarPrimitive.Image`. Default is `""`, which marks the avatar as
decorative and removes it from the accessibility tree. Every callsite on
the workspaces page already renders the human-readable name (owner,
template, organization, user) as adjacent text, so decorative-by-default
is the WCAG-correct behavior. Callers that need a meaningful alt can
override.
- `AvatarData`: thread an optional `alt` through to the internal default
`Avatar`.
- `WorkspacesTable` `IconAppLink` `ExternalImage`: pass `alt=""`. The
wrapping `BaseIconLink` already exposes the app name through an
`sr-only` span on the link.
- `BatchDeleteConfirmation` resource icons `ExternalImage`: pass
`alt=""`. The resource-type label sits next to each icon.
- `WorkspacesPageView.stories.tsx` `AllStates`: add a play function that
scans the rendered canvas and asserts every `<img>` has an `alt`
attribute, to prevent regressions.

## Validation

- `pnpm check`, `pnpm lint`, `pnpm format` clean.
- `pnpm test -- src/pages/WorkspacesPage/WorkspacesPage.test.tsx` passes
(13/13).
- Pre-commit (`make pre-commit`) passes locally.

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

### Root cause

The `Avatar` component (`site/src/components/Avatar/Avatar.tsx`)
rendered `AvatarPrimitive.Image` without an `alt` attribute. Every
consumer (`AvatarData`, `TopbarAvatar`, workspace table rows, filter
menus, empty state, batch dialogs, "New workspace" dropdown) inherited
the missing-alt bug, which is why a single page produced ~52 violations.

### Fix

1. Make `Avatar` accept an `alt` prop, default `""`, and forward it to
the underlying `<img>`. Drop-in compatible with every existing call.
2. Mirror the prop on `AvatarData` so callers can label the implicit
avatar without composing their own.
3. Explicitly mark the workspaces-page `ExternalImage` callsites as
decorative because each is paired with adjacent text.
4. Lock the behavior with a Storybook play function so a future
regression on the workspaces page fails CI.

### Why `alt=""` by default

All workspaces-page avatars are rendered next to the corresponding name.
Per WCAG, repeating that name in the image's alt text would only add
noise for screen-reader users. Empty alt removes the image from the
accessibility tree, which is the correct decorative pattern.

</details>

---

_PR opened by Coder Agents on behalf of @tracyjohnsonux._
2026-06-12 13:25:00 -07:00
Asher ad127d03b9 chore: refactor mock websocket to make open explicit (#26323)
Callers can now choose when to open and emit the initial message. This
will enable finer testing for some incoming bug fixes related to the
timing of dynamic parameter sockets and requests.

Add a callback to preserve the current behavior for existing tests and make
the transition easier.  Future tests can omit the callback and emit the events
under whatever condition they need.

The only behavioral changes are:
- the web socket error test now emits a close error without first
opening to accurately simulate a failure to connect at all.
- add some missing `diagnostics` to some responses (just to be
thorough).
- change one of the IDs to match in two tests (for consistency).
2026-06-12 10:11:48 -08:00
Jaayden Halko 3184ed9e9e chore: remove horizontal wheel scrolling (#26332) 2026-06-12 16:09:13 +01:00
Jeremy RuppelandMcKayla はな dd7d2653ca feat: add template builder module catalog structure and go:embed wiring (#25909)
Scaffolds the `coderd/templatebuilder` package for the guided template
builder ([DEVEX-272](https://linear.app/codercom/issue/DEVEX-272),
[RFC](https://www.notion.so/coderhq/RFC-Guided-Template-Creation-Workflow-342d579be59280dfbf8eea2e5006dbda)).

Adds the module catalog types and `go:embed` wiring that the template
builder endpoints will use:

- `codersdk.TemplateBuilderModule`, `TemplateBuilderModuleVariable`, and
related types matching the RFC schema
- Internal `ModuleManifest` type with `go:embed` wiring to bundle
`module.json` files from `coderd/templatebuilder/modules/`
- `LoadModules()` with defensive copy, unexported
`parseModulesFromFS(fs.FS)` for test isolation, `ToSDK()` conversion
- Real `code-server` module manifest as the first catalog entry
- Strict validation: ID uniqueness, version non-empty, variable
type/name validation, `DisallowUnknownFields`, and requiring
`module.json` in every module directory
- Tests via internal `catalog_internal_test.go` (for
`parseModulesFromFS` with `fstest.MapFS` fixtures) and external
`catalog_test.go` (for `LoadModules` and `ToSDK`), covering multi-module
parsing, all variable types, validation errors, nil-slice normalization,
and full SDK field assertions

> [!NOTE]
> Generated with [Coder Agents](https://coder.com/agents) by
@jeremyruppel

---------

Co-authored-by: McKayla はな <mckayla@hey.com>
2026-06-12 09:40:36 -04:00
Danielle Maywood 79a28bad72 feat(site): group shared agents in sidebar (#26328) 2026-06-12 12:39:53 +01:00
Hugo Dutka 4debd23cbb fix: chatd refactor (#26270)
Implements the chatd stabilization RFC.

Combines:
- https://github.com/coder/coder/pull/25908
- https://github.com/coder/coder/pull/25923
- https://github.com/coder/coder/pull/26109
- https://github.com/coder/coder/pull/26110
- https://github.com/coder/coder/pull/26111
- https://github.com/coder/coder/pull/26112
2026-06-12 13:33:12 +02:00
Danny Kopping 4a07f61c50 refactor!: remove interceptions API, request logs view, and associated code (#26213)
## Summary

Removes the deprecated `/api/v2/aibridge/interceptions` endpoint and the
Request Logs frontend page, both replaced by the session-based view.

Closes https://linear.app/codercom/issue/AIGOV-266
Closes https://linear.app/codercom/issue/AIGOV-324

## Changes

### Backend
- Remove `GET /api/v2/aibridge/interceptions` HTTP handler and route
- Remove SDK types and client method (`AIBridgeInterception`,
`AIBridgeTokenUsage`, `AIBridgeUserPrompt`, `AIBridgeToolUsage`,
`AIBridgeListInterceptionsResponse`, `AIBridgeListInterceptionsFilter`)
- Remove SQL queries `CountAIBridgeInterceptions` and
`ListAIBridgeInterceptions`
- Remove `searchquery.AIBridgeInterceptions` parser
- Remove dbauthz wrappers, in-memory implementations, metrics, and mocks
for the interceptions list queries
- Remove the `coder aibridge interceptions list` CLI command and golden
files
- Regenerate API docs, swagger, mocks, and metrics

The `/models`, `/clients`, and `/sessions` endpoints stay; the sessions
list page still consumes all three.

### Frontend
- Delete the entire `RequestLogsPage/` directory (page, view, row,
filter, stories, tests)
- Remove the `/aibridge/request-logs` route and its lazy import
- Remove the `getAIBridgeInterceptions` API method,
`paginatedInterceptions` query, and mock interception entities
- `git mv` the shared filter and icon components used by the sessions
pages:
- `RequestLogsPage/RequestLogsFilter/{Client,Model,Provider}Filter.tsx`
→ `AIBridgePage/filters/`
- `RequestLogsPage/icons/AIBridge{Client,Model,Provider}Icon.tsx` →
`AIBridgePage/icons/`
- Drop the `getProviderIconName` hack and the duplicate `anthropic-neue`
icon case now that the FIXME no longer applies

## Commits

1. `refactor: remove interceptions API and request logs view` — the bulk
removal, with explicit renames for the shared filter/icon files.
2. `refactor(site/src/pages/AIBridgePage): drop getProviderIconName
hack` — cleanup of the FIXME that depended on RequestLogsPage existing.

> [!NOTE]
> Generated by Coder Agents on behalf of @dannykopping
2026-06-12 07:50:46 +02:00
Ethan f13c858482 fix(site): add openai-compatible endpoint placeholder (#26017)
OpenAI-compatible provider endpoints need to include the upstream
OpenAI-compatible prefix, typically `/v1`, because Coder appends request
suffixes such as `/chat/completions`, `/responses`, and `/models`. The
generic OpenAI-compatible provider form did not show an example
endpoint, so it was easy to save a host-only URL that looked valid but
would fail when used.

Add `https://provider.example.com/v1` as the Endpoint placeholder for
the OpenAI-compatible provider, matching the documented example URL
shape.
2026-06-12 11:51:38 +10:00
Ethan 7632e73608 refactor(site/src): extract shared workspace-app frame module (#26088)
Extracts the workspace app iframe, wildcard warning, and workspace-app
helper functions out of TaskPage into shared `site/src/modules/apps`
modules. Existing agent and app lookups in the task chat helpers,
download-logs dialog, and workspaces table now route through the shared
`workspaceApps` helpers instead of duplicating resource-flattening
logic. The extracted frame preserves the existing preview-only toolbar
behavior, and its open-in-new-tab link gains `rel="noreferrer"` to
harden against tabnabbing.

Relates to CODAGT-346
2026-06-12 11:51:20 +10:00
Andrew Aquino e8489d556e test: await copy created token button before clicking (#26174)
fixes DEVEX-375

Replaces `getByRole` with async `findByRole`, which returns a promise /
rejects if no matching element is found after a default timeout of
1000ms

Co-written with Coder Agents. Relevant chat responses:

[I couldn't repro locally, so I inquired if there was a commit/PR that
fixed the flake within the past 3 weeks]

>No, this flake has not been fixed. There have been zero commits to
`CreateTokenPage`, `CopyButton`, `CodeExample`, or `useClipboard.ts`
since the failing CI run (13bf0e11f1, May 20).

>`getByRole` is synchronous, so it doesn't wait for the success modal
(containing the "Copy code" button) to render after the `createToken()`
mutation resolves. When the mutation is slow, the DOM still shows the
form (Cancel / Create token), and the query fails.
2026-06-11 16:36:16 -07:00
Danielle Maywood ba51ee8f98 refactor(site/src/pages/AgentsPage): centralize setup notice rendering (#26134) 2026-06-11 12:43:53 +01:00
Danielle Maywood f865281177 refactor(site): remove CSSProperties assertions (#26234) 2026-06-11 11:21:34 +01:00
Danielle Maywood e440771b3e fix(site): allow single-line diff comments (#26241) 2026-06-11 10:34:05 +01:00
Danielle Maywood 68efed86fa fix(site/src/pages/AgentsPage/components): gate transcript copy actions and keep live thinking row in flow (#26214) 2026-06-11 10:08:10 +01:00
Jaayden Halko 5ab25b3ff6 fix(site): add a custom copy/paste menu to the web terminal (#26015)
## Summary

Fixes [CODAGT-415](https://linear.app/codercom/issue/CODAGT-415).

Right-clicking selected text in the web terminal on Windows (and Linux)
showed
the browser's image actions ("Copy image", "Save image as") instead of
copy/paste. The terminal uses xterm.js with the canvas/WebGL renderer,
so the
underlying element is a `<canvas>`, which Chromium and Firefox treat as
an
image. xterm.js tries to retarget the menu by moving a hidden textarea
under
the cursor, but on Windows and Linux the browser's own non-native
context menu
locks onto the canvas before that workaround lands.

## Change

Wrap the terminal in the shared Radix `ContextMenu` so right-click shows
a
custom **Copy** / **Paste** menu instead of the browser default:

- **Copy** reuses the existing copy-on-select clipboard path
(`getSelection()`
  + `copyToClipboard`). It is disabled when there is no selection.
- **Paste** reads the clipboard and uses xterm's `paste()`, which
respects
  bracketed-paste mode.
- The menu is gated to non-macOS (`disabled={isMac()}` on the trigger).
macOS
renders native context menus that already expose working copy/paste
across
  Chrome, Firefox, and Safari, so its default is left untouched.

## Platform scope

| Platform | Behavior |
| --- | --- |
| Windows (Chromium / Firefox) | Custom Copy/Paste menu (fixes the bug)
|
| Linux (Chromium / Firefox) | Custom Copy/Paste menu |
| macOS (Chrome / Firefox / Safari) | Native menu preserved (already
works) |

## Testing

- `TerminalPage.test.tsx`: on non-macOS, right-click suppresses the
native menu
  and shows the Copy/Paste menu; on macOS the native menu is preserved.
- `TerminalPage.stories.tsx`: new `RightClickMenu` story opens the menu
via a
  `play` function for real-browser and visual coverage.
- `tsc`, `biome`, and `make pre-commit` (gen/fmt/lint/build) pass
locally.

<details>
<summary>Decision log</summary>

- The issue was originally reported as Windows-only. Hands-on testing
confirmed
macOS is not affected: Chrome, Firefox, and Safari on macOS all show a
working
copy/paste menu. The difference is the menu implementation: macOS uses
native
  OS context menus (which pick up xterm's repositioned textarea), while
Chromium/Firefox on Windows and Linux draw their own menu that targets
the
  `<canvas>` directly.
- Root cause is the canvas/WebGL renderer plus the unreliability of
xterm's
textarea-repositioning workaround on non-native menus, not the operating
  system itself.
- A custom menu (rather than just `preventDefault`) was chosen so users
keep an
  explicit copy/paste affordance on the affected platforms. A bare
  `preventDefault` removes the menu entirely.
- Scope is gated to non-macOS to avoid regressing the working native
menu on
macOS. Rejected alternatives: suppressing/replacing on all platforms
(regresses
macOS), and Windows-only (misses Linux, which shares the same non-native
menu).

</details>

---

Generated by Coder Agents on behalf of @jaaydenh.
2026-06-11 09:12:15 +01:00
Ethan 2e47d33c2c fix(site/src/modules/resources): restore log auto-expand on script failure (#26237)
#26124 introduced a regression on `main`: `AgentRow ›
NonStartupScriptError` fails because the refactor replaced
`hasAgentIssues` (which covered both connectivity and script issues)
with `hasConnectivityIssues` only in the `showLogs` condition. For a
`ready` agent with a failed script but no connectivity issues,
`showLogs` becomes false, logs never load, and the failed script tab
never renders. The PR's own behavior table said logs should still
auto-open in this case — it was an implementation oversight, not an
intentional change.

Fix by including `hasScriptIssues` in the `showLogs` condition alongside
`hasConnectivityIssues`, restoring the auto-expand behavior from #25442
without touching connectivity badge styling.

> **Note:** This reached `main` undetected because `test-js` in CI only
runs `--project=unit`; the Storybook interaction tests
(`--project=storybook`) that caught this are not a required check. When
Chromatic is switched off, `--project=storybook` should be added to the
required gate.

Refs #26124, #25442
2026-06-11 05:45:59 +00:00
Atif Ali 9e1c502ece fix(site): delink agent health from script failures (#26124) 2026-06-11 09:30:15 +05:00