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

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

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

## Changes

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


##### Before


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

##### After


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

---

_This PR was generated by Coder Agents on behalf of @jeremyruppel._
2026-08-10 15:57:51 -04:00
Steven Masley 053b38944d fix(coderd): render collected_at as UTC RFC3339 in the agent metadata aggregate (#27991)
Follow-up to #27934; this fix was pushed to the branch after the
squash-merge and missed it.

`jsonb_build_object` renders timestamptz in the session `TimeZone`,
which Coder never pins, and `collected_at` defaults to year 1 until the
agent's first report. On a non-UTC Postgres session a
registered-but-never-collected item renders with an LMT second-offset
(even `BC`, e.g. `0001-12-31T19:03:58-04:56:02 BC`), which Go's RFC3339
parsing rejects - a 500 for the entire list page whenever
`include_agent_metadata` is used.

- `to_char(... AT TIME ZONE 'UTC', ...)` pins the rendering;
never-collected items round-trip as Go's zero time.
- The test now runs against a named-zone database
(`dbtestutil.WithTimezone("America/Caracas")`) and requests a registered
but never-collected key; it reproduces the 500 without the fix.

Also contains the failure mode Go-side: an unparsable aggregate now
degrades to missing metadata for that workspace (with a warning log)
instead of failing the entire page. The SQL fix prevents the known
cause; the containment covers any future one. The test still catches
regressions because it asserts the metadata values, not just a 200.

---

Authored by Coder Agents on behalf of @Emyrk.
2026-08-10 14:53:48 -05:00
J. Scott Miller 66b065323b feat: log rate-limited external auth token validation (#26754)
When `ValidateToken` keeps a token because the external auth validation
endpoint was rate-limited (a `403` with rate-limit headers or a `429`),
it returns `valid=true` without provider confirmation. Previously this
happened silently, so operators couldn't tell a provider-confirmed token
from one kept optimistically during a rate limit.

This adds a `Logger` to `externalauth.Config` and emits a `Warn` (with
`provider_id`, `provider_type`, `status_code`, and `reason`) on those
rate-limit branches. It also adds a
`coderd_oauth2_external_requests_rate_limited_total{name, source,
status_code}` counter, incremented in the instrumented round tripper
whenever a provider returns a rate-limited response. The rate-limit
detection is the shared `xhttp.IsRateLimited` (in `coderd/util/xhttp`),
used by both the tripper and `ValidateToken` so the metric and the
validation decision share one definition; no extra wiring is needed
since `ValidateToken` already routes through the instrumented client
with `source="ValidateToken"`.

One deliberate behavioral change rides along: rate-limit detection now
also recognizes the unprefixed `RateLimit-Remaining` header (GitLab, and
the IETF draft rate-limit headers), so a `403` with
`RateLimit-Remaining: 0` is treated as optimistically valid where it was
previously treated as revoked. All other valid/invalid decisions are
unchanged. `TestValidateToken` asserts the warning's fields on the
rate-limited cases and no warning for revocations, `401`, and confirmed
responses; `promoauth` and `xhttp` tests cover the detector and the new
counter.

<details>
<summary>Manual testing</summary>

The signals fire on the external-auth status check (`GET
/api/v2/external-auth/{id}`), which calls `ValidateToken`. To force a
rate-limited response, point a provider's `validate_url` at a mock that
returns the rate-limit shape:

1. Run a mock returning `429` on one path and `403` +
`X-RateLimit-Remaining: 0` on another.
2. Start `coder server` with `--prometheus-enable` and external auth
providers whose `validate_url` point at those mock paths (e.g.
`CODER_EXTERNAL_AUTH_0_VALIDATE_URL=http://127.0.0.1:5599/429`).
3. Create a stored link, either complete the OAuth flow, or insert a row
into `external_auth_links` with a future `oauth_expiry` (token contents
are irrelevant; the mock rejects regardless).
4. `curl` the status endpoint with a session token, then check:
- coderd logs for the `Warn` (`reason=status_code` for `429`,
`reason=rate_limit_headers` for `403`),
- the metrics endpoint for
`coderd_oauth2_external_requests_rate_limited_total{...,status_code="429"|"403"}`.

Notes: `scripts/testidp -429` only rate-limits `/oauth2/userinfo`, not
the `/external-auth-validate/...` path, so it does not exercise this;
use a mock `validate_url`. The default Prometheus port `2112` may
already be taken on dogfood workspaces, set `CODER_PROMETHEUS_ADDRESS`
to a free port.

</details>

🤖 Generated with the help of Coder Agents on behalf of @jscottmiller.
2026-08-10 14:43:16 -05:00
Bobby Ho bd693ad4ae fix: raise test-go-pg timeout budget, lower macOS parallelism (#27997)
`test-go-pg (macos-latest)` has recurred three times on
[coder/internal#1365](https://github.com/coder/internal/issues/1365),
most
recently as the `cli` package hitting its own `go test -timeout 20m`
after
several minutes of runner-side scheduling delay, which marks hundreds of
in-flight subtests as failed instead of surfacing the actual cause.

Raise `GOTEST_FLAGS -timeout` from `20m` to `25m` and the matching
`timeout-minutes` on every job that shares it (`test-go-pg`,
`test-go-pg-17`, `test-go-race-pg` in `ci.yaml`; `flake_go` in
`flake-go.yaml`; `test-go-pg` in `nightly-gauntlet.yaml`) from `25` to
`30`, preserving the 5-minute margin that lets `go test`'s own timeout
fire before GitHub cancels the job and produce a goroutine dump for a
genuine hang.

Also lower macOS `test-parallelism-tests` from `16` to `8`, matching
Linux, to test whether the 2x core oversubscription is contributing
scheduler contention. Windows keeps `16`; nothing in the current
evidence
implicates it.

This is a mitigation, not a confirmed root cause; the runner scheduling
delay itself is still unexplained.

Refs coder/internal#1365

## AI disclosure

Per [AI Contribution
guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING):
this PR was primarily authored by Claude Code, directed by @BobbyHo,
based
on triage of the linked ticket's CI-flake-bot comments and a review of
the
current `Makefile`/`ci.yaml`/`flake-go.yaml`/`nightly-gauntlet.yaml`
timeout configuration.

**Verification:**

- `make lint/actions/actionlint` and `make lint/actions/zizmor` both
pass
  clean on the three edited workflow files.
- `make pre-commit` passes (includes `make gen`, `make fmt`, `make
lint`,
  and a full local build).
- All three edited workflow YAMLs parse (`ruby -ryaml`) and
  `make -n test TEST_PACKAGES="./cli/..."` confirms `GOTEST_FLAGS`
  resolves to `-timeout 25m` as intended.
- This is a config-only change (no application code touched); the
  intended effect can only be confirmed by watching real `test-go-pg`
(macOS) runs on this PR and on `main` after merge, since the underlying
  runner-stall failure is intermittent.
2026-08-10 12:29:05 -07:00
Bobby HoandClaude Opus 5 16c58770f8 feat: constrain the OAuth2 client type column (#27931)
Extracted from #27873 so the schema change can be reviewed for migration
safety on its own. #27873 will rebase onto this.

`client_type` decides whether the token endpoint validates a client
secret at all, and the column accepts any text: nullable, no `CHECK`, no
enum. No Go path can write a bad value today, and `IsPublic` fails
closed on anything unrecognized, so the read side is safe. What the
schema still permits is the problem: a future migration writing
`'public'` onto a row that holds a secret turns off client
authentication for that app with nothing to catch it, no constraint, no
log, no audit entry, no test.

`000565` adds `CHECK (client_type IN ('confidential', 'public'))` and
`NOT NULL`. The `UPDATE` ahead of it should touch zero rows, since
migration `000344` added the column with a default of `'confidential'`
and backfilled with `COALESCE`; it is there so `SET NOT NULL` cannot
fail on an unexpected row. Both `ALTER`s take `ACCESS EXCLUSIVE` and
scan a table holding one row per registered OAuth2 client, so the lock
is brief.

## The second migration, and why it aligns the way it does

Two columns describe the same fact and can currently contradict each
other.

`token_endpoint_auth_method` is the client's own declaration: registered
client metadata under RFC 7591 §2, where `"none"` is defined to mean the
client is public and has no secret. `client_type` is Coder's derived
copy, and it is what the token endpoint enforces on. RFC 7591 defines no
`client_type` metadata field; the column exists only as a
denormalization.

Registration used to persist the declaration verbatim while hardcoding
`client_type` to `'confidential'`, so rows exist declaring `"none"` on a
client stored confidential that was issued, and still requires, a real
secret. A client that reads its own metadata and believes it is public
will drop that secret and stop being able to exchange codes.

`000566` aligns the declaration to what is enforced, not the reverse.
Deriving enforcement from the declaration would reclassify every such
client as public and stop requiring the secret it holds, which is a
silent authentication downgrade. The down migration is deliberately
empty: the previous values are not recorded, and restoring them would
only reinstate metadata that tells a client to authenticate in a way the
server rejects.

## Application changes

`SET NOT NULL` changes the generated field from `sql.NullString` to
`string`, so the three write sites are updated to match. That is the
entire application diff and no behavior depends on it.

Refs
https://linear.app/codercom/issue/ENG-3029/oauth2-support-public-client

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 10:49:02 -07:00
Nick Vigilante 2f34e1abd0 ci: add scheduled audit-docs-paths workflow (#27245)
## What

Adds `.github/workflows/audit-docs-paths.yaml`, a scheduled workflow
that runs the docs-URL drift audit (`site/scripts/audit-docs-paths.mjs`,
added in #25740) on a weekly cron and on demand, so drift is caught
automatically instead of only when someone runs the script by hand.
Scheduling was suggested by @bpmct on #25740.

## How it works

- **Triggers:** `schedule` (weekly, Monday 09:00 UTC — same cadence as
`weekly-docs`) and `workflow_dispatch`.
- **Checks out both repos:** `coder/coder` (root) and `coder/coder.com`
(into `coder.com/`, read with the `cdrci` CI-bot token). The audit
covers references in both repos.
- **Runs the audit** with absolute `--roots` (required, otherwise the
report can't classify findings by repo).
- **Always** uploads the dated report as the `audit-docs-paths-report`
artifact and writes it to the run summary.
- **On findings:** opens or updates a single deduplicated tracked issue
with the report, and fails the run (red check). **On a clean run:**
closes that issue.

## Enabling (dormant until then)

The audit reads **coder/coder.com, a private repo**, which the default
`GITHUB_TOKEN` can't read, so the coder.com checkout uses the existing
**`cdrci`** CI-bot token (`secrets.CDRCI_GITHUB_TOKEN`) — already used
for cross-repo checkouts in `release.yaml`/`tag-and-release.yaml`, and
`cdrci` is a coder.com collaborator (verified). No new App to stand up.
The job is gated behind `vars.AUDIT_DOCS_PATHS_ENABLED` so it merges
dormant and can be validated before going live.

To turn it on:
1. Set `vars.AUDIT_DOCS_PATHS_ENABLED = 'true'`.
2. Run once via `workflow_dispatch` to confirm the end-to-end run.

## Also in this PR

Removes the dormant `audit-docs-paths` job embedded in
`weekly-docs.yaml` (added in #25740, gated off pending the same
credential). The new dedicated workflow supersedes it; the
`weekly-docs.yaml` diff is exactly that job removal.

## Validation

- `actionlint -shellcheck= -ignore set-output` passes locally; PR
`title`, `lint-actions`, and `lint-docs` are green.
- **Credential check:** `cdrci` is a collaborator on coder/coder.com
(read access confirmed); `secrets.CDRCI_GITHUB_TOKEN` already exists in
this repo. (Note: `cdrci2` is *not* a coder.com collaborator, so an
earlier `CDRCI2_` attempt was corrected to `CDRCI_`.)
- **Pre-flight audit against current `main` (both repos): 0 findings** —
148 `/docs/*` redirect rules indexed; 1846 coder/coder + 432 coder.com
TS/TSX files scanned. So a `workflow_dispatch` on `main` today passes
green with no issue filed (the "empty audit succeeds" criterion). The
failure path can be checked by injecting a stale path on a throwaway
branch.

## Decisions for review

- **Mechanism** = tracked issue + failed check + artifact ("both" from
the issue). Easy to narrow to issue-only or fail-only.
- Reused `AUDIT_DOCS_PATHS_ENABLED` and removed the embedded job rather
than adding a second gate.
- Named the file `.yaml` to match the repo's other docs workflows (the
issue text said `.yml`).

Linear: https://linear.app/codercom/issue/DOCS-366
2026-08-10 13:40:44 -04:00
Michael Suchacz ad100452d4 fix(aibridge): use latest streaming chat usage instead of cross-chunk sum (#27967)
## Problem

CODAGT-906: chats using OpenAI-compatible backends (e.g. poolside)
through the AI Bridge persist token usage inflated 105x-640x, which
falsely triggers automatic chat compaction on every turn.

The chat-completions streaming interceptor summed usage across every SSE
chunk of one upstream stream and rewrote each relayed usage-bearing
chunk with that running sum. Spec-compliant OpenAI emits usage once
(final chunk with `stream_options.include_usage`), so the sum equals the
final value. vLLM-style backends emit cumulative usage snapshots on
every chunk, so the relayed final usage becomes roughly `N_chunks x
prompt_tokens` (e.g. 417,012 persisted for a ~6,000-token context).
chatd persists that value per assistant message and its compaction
trigger reads it as context occupancy.

## Fix

Track the latest usage-bearing chunk's raw usage (last-wins) in the
stream processor, updating only when a chunk actually carries usage so a
trailing usage-less chunk cannot zero it. `marshalChunk` relays that
value and `recordTokenUsage` records the same value, unifying relayed
and recorded usage. Last-wins is correct for both shapes: a single final
usage chunk, and cumulative snapshots where each snapshot already
includes all prior tokens.

Per-iteration semantics are unchanged: each tool-loop iteration has its
own processor, and the final iteration's usage is what the client sees.

## Tests

- `TestStreamProcessorUsage` (internal): cumulative snapshots with a
trailing usage-less chunk, and the spec-compliant final-only shape;
asserts relayed and recorded usage equal the last snapshot.
- New txtar fixture `streaming_cumulative_usage_injected_tool.txtar`
with per-chunk cumulative usage plus an injected tool call; asserts
client-visible final usage through the full interceptor.
- Red-green verified: with the fix reverted, the internal test reports
zeroed usage (trailing chunk overwrite) and the fixture test reports
18000 summed prompt tokens instead of 6000.

The blocking (non-streaming) path deliberately keeps its cross-iteration
summation for external clients and is untouched. Remote dogfood UAT
validated chat streaming, tool calls, plausible usage numbers, and zero
spurious compactions.

> Mux acted on Mike's behalf to author this change.
2026-08-10 19:32:24 +02:00
Susana Ferreira 5efa7abe7d fix: only write AI model prices that changed (#27923)
Previously, the AI Gateway price seeder rewrote every row of
`ai_model_prices` on each server start, because `ON CONFLICT` fires on a
key conflict rather than on a value difference. `updated_at` therefore
recorded when the server last restarted rather than when a price last
changed.

Guard the `DO UPDATE` branch so a conflicting row is only rewritten when
one of its four prices differs. The comparison uses `IS DISTINCT FROM`
rather than `<>` because the price columns are nullable, and `<>` yields
NULL when either side is NULL, which would skip the update and leave a
stale price in place.

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

> [!NOTE]
> Initially generated by Claude Opus 5, modified and reviewed by
@ssncferreira
2026-08-10 16:33:48 +01:00
Susana Ferreira 27414788f7 chore: use 'AI spend' and 'approximate' in budget UI (#27977)
The "AI budget" column shows spend against the configured limit, not the
limit itself, so "AI spend" describes what it actually displays. Renamed
in both the groups table and the group members table.

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

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

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

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

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

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

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

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

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

---

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

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

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

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

## Sidebar summary

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

---

PR generated with Coder Agents
2026-08-10 08:44:56 -04:00
Jakub Domeracki 8c2f7adeb1 revert: "fix: markdown rendering improvements" (#27979)
This reverts commit 07f79af65b ("fix:
markdown rendering improvements").

The revert was applied cleanly with `git revert` and restores the
notification rendering pipeline to its prior state, including:

- `coderd/notifications/dispatch/smtp.go` and `smtp/html.gotmpl`
- `coderd/notifications/notifier.go` and `render/gotmpl.go`
- Removal of `coderd/notifications/render/sanitize_test.go` and
`smtp_internal_test.go` additions
- Regenerated SMTP golden templates under
`coderd/notifications/testdata/`

`go build ./coderd/notifications/...` passes on the reverted tree.

---

_This PR was generated by Coder Agents on behalf of @jdomeracki-coder._
2026-08-10 12:58:01 +02:00
Marcin Tojek cfeae56bed chore(docs): update release docs for v2.35.4 (#27972)
Automated docs update for v2.35.4 release.

Created by `releasetui`.
2026-08-10 11:53:47 +02:00
Michael Suchacz 95e8b71d03 fix(coderd): start test AI bridge after config in automatic title tests (#27971)
Fixes the reopened flake tracked in CODAGT-876 / coder/internal#1629.

## Problem

The Aug 10 recurrence was not the previously fixed subtests failing
again: the nightly-gauntlet macos run ([job
log](https://github.com/coder/coder/actions/runs/31355808516/job/93355150162))
flaked in the sibling test
`TestPostChats_AutomaticTitleGenerationPasteOnly`, which the flake
investigator matched to the existing issue.

Both `TestPostChats_AutomaticTitleGeneration*` tests still used
`newChatClientWithAPI`, which starts the in-process AI Gateway daemon
before the test creates its provider/model config. The daemon's
synchronous initial provider load therefore sees zero providers, and
route availability depends on the asynchronous pubsub-driven reload
racing the one-shot automatic title generation that `CreateChat` kicks
off. When the reload loses (initial load at `.575` with
`provider_count=0`, title request at `.907` hitting `route not
supported`, reload landing at `1.029`), the title candidate fails
without retry and the test times out waiting for the `propose_title`
request.

## Fix

Convert both tests to the pattern #27564 established for the
`TestRegenerateChatTitle`/`TestProposeChatTitle` subtests:
`newChatClientWithoutAIBridge`, create the model config, then
`aibridgedtest.StartTestAIBridgeDaemon`, so the daemon's synchronous
initial load already contains the route. The existing `NoPubsubDelivery`
subtest guards that initial-load invariant, so no new guard test is
added.

## Validation

- Deterministic red-green via the isolated-pubsub technique: old
ordering with the pubsub leg removed reproduces the exact CI signature
(`provider_count=0`, `route not supported`, timeout at the
`titleRequested` wait); the new ordering passes with the pubsub leg
still removed, proving the synchronous initial load alone provides the
route.
- `go test ./coderd -run 'TestPostChats_AutomaticTitleGeneration'
-count=10`
- `go test ./coderd -run 'TestRegenerateChatTitle|TestProposeChatTitle'
-count=1`
- `make lint` and `make pre-commit` via hooks.

> Opened by Mux on Mike's behalf.
2026-08-10 11:37:59 +02:00
Jakub Domeracki 07f79af65b fix: markdown rendering improvements
Improvements to markdown rendering in notification emails:

- More consistent escaping of values interpolated into notification templates
- Stricter link handling in the notification email renderer, scoped to the notification rendering path
- HTML escaping of values interpolated into the outer email template

- Expanded unit and end-to-end coverage of the notification rendering pipeline
- `make gen` run to regenerate golden files for SMTP and webhook notification templates
2026-08-10 10:45:19 +02:00
Danielle Maywood 192842c8f2 fix(site/src): treat chat deleted watch events as archive instead of eviction (#27921) 2026-08-10 09:29:38 +01:00
Danielle Maywood 19fdc23d63 fix(site/src): fan chat message upserts out to every containing page (#27912) 2026-08-10 09:08:05 +01:00
Marcin Tojek 0414948454 chore(docs): update release docs for v2.34.8 (#27970)
Automated docs update for v2.34.8 release.

Created by `releasetui`.
2026-08-10 09:52:49 +02:00
Jake Howell bab9963a9a fix(site): defer external app API key generation to on-click (#27907)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

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

## Problem

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

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

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

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

## Change

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

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

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

## Affected call sites

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

## Testing

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

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

Also verified:

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

## Manual verification checklist (recommended before merge)

- With an external app that uses `$SESSION_TOKEN` (e.g. JetBrains
Gateway), open DevTools → Network filtered on `users/me/keys`, reload
`/workspaces` and the workspace detail page, and confirm **no** `POST`
fires on render.
- Confirm a `POST` fires only when the app link is clicked, and the app
opens correctly.
2026-08-10 14:44:35 +10:00
dependabot[bot] 1e578a69a4 chore: bump github.com/go-git/go-git/v5 from 5.19.1 to 5.19.2 (#27950)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git)
from 5.19.1 to 5.19.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/go-git/go-git/releases">github.com/go-git/go-git/v5's
releases</a>.</em></p>
<blockquote>
<h2>v5.19.2</h2>
<h2>What's Changed</h2>
<ul>
<li>build: Update module golang.org/x/crypto to v0.52.0 [SECURITY]
(releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@​go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2150">go-git/go-git#2150</a></li>
<li>build: Update module github.com/go-git/go-git/v5 to v5.19.1
[SECURITY] (releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@​go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2141">go-git/go-git#2141</a></li>
<li>build: Update module golang.org/x/net to v0.55.0 [SECURITY]
(releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@​go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2152">go-git/go-git#2152</a></li>
<li>git: Worktree: Add stores index entires with backslashes on Windows
by <a href="https://github.com/joshblum"><code>@​joshblum</code></a> in
<a
href="https://redirect.github.com/go-git/go-git/pull/2262">go-git/go-git#2262</a></li>
<li>storage: dotgit, reject path traversal in reference names by <a
href="https://github.com/pjbgf"><code>@​pjbgf</code></a> in <a
href="https://redirect.github.com/go-git/go-git/pull/2254">go-git/go-git#2254</a></li>
<li>build: Update module golang.org/x/net to v0.56.0 [SECURITY]
(releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@​go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2267">go-git/go-git#2267</a></li>
<li>build: Update module golang.org/x/text to v0.39.0 [SECURITY]
(releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@​go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2268">go-git/go-git#2268</a></li>
<li>[v5] git: worktree, make the filesystem wrapper a symlink-safe
boundary by <a href="https://github.com/pjbgf"><code>@​pjbgf</code></a>
in <a
href="https://redirect.github.com/go-git/go-git/pull/2277">go-git/go-git#2277</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/go-git/go-git/compare/v5.19.1...v5.19.2">https://github.com/go-git/go-git/compare/v5.19.1...v5.19.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/go-git/go-git/commit/3eeb238da61eb9c7a324f3ee04f990ce89175642"><code>3eeb238</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2277">#2277</a>
from go-git/checkout-v5</li>
<li><a
href="https://github.com/go-git/go-git/commit/008a78f2dd86f52544ddff8b8e8ddeecdf3f7aab"><code>008a78f</code></a>
git: worktree, make the filesystem wrapper a symlink-safe boundary</li>
<li><a
href="https://github.com/go-git/go-git/commit/2263fb5f022dde90b1c2845f028d3e37e161f2b8"><code>2263fb5</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2268">#2268</a>
from go-git/renovate/releases/v5.x-go-golang.org-x-t...</li>
<li><a
href="https://github.com/go-git/go-git/commit/77b76250d93ec83e2c897638d8a3847b1bfaa38d"><code>77b7625</code></a>
build: Update module golang.org/x/text to v0.39.0 [SECURITY]</li>
<li><a
href="https://github.com/go-git/go-git/commit/85ea767be2b2281693e61afe83911e12c86d6eb7"><code>85ea767</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2267">#2267</a>
from go-git/renovate/releases/v5.x-go-golang.org-x-n...</li>
<li><a
href="https://github.com/go-git/go-git/commit/198675a07b3b8f4eb8f51bf188663a13bb0d9e1a"><code>198675a</code></a>
build: Update module golang.org/x/net to v0.56.0 [SECURITY]</li>
<li><a
href="https://github.com/go-git/go-git/commit/4a0e66d555de5f9a30c31e2df64f445f42bd01e7"><code>4a0e66d</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2254">#2254</a>
from pjbgf/v5-dotgit-ref-name-containment</li>
<li><a
href="https://github.com/go-git/go-git/commit/3b306ef83bd05194a30ce820eed7ed61c3084b5f"><code>3b306ef</code></a>
storage: dotgit, align reference-name safety with refname_is_safe</li>
<li><a
href="https://github.com/go-git/go-git/commit/f3d0cc150b39ae1dc47406a5c170464286914610"><code>f3d0cc1</code></a>
storage: dotgit, reject path traversal in reference names</li>
<li><a
href="https://github.com/go-git/go-git/commit/979cfe9c561d3ced778c88d9cde6db3297e6ed1d"><code>979cfe9</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2262">#2262</a>
from joshblum/joshblum/to-slash-v5</li>
<li>Additional commits viewable in <a
href="https://github.com/go-git/go-git/compare/v5.19.1...v5.19.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-git/go-git/v5&package-manager=go_modules&previous-version=5.19.1&new-version=5.19.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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

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

---

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

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
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-08-09 07:42:17 +00:00
Jake Howell b2cfc4e530 refactor(site): move Add users into <SettingsHeader /> (#27906)
Move the Add users action into SettingsHeader on the organization
Members page and group detail page, matching the Users page layout. It
no longer sits inline with the filters.

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

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

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

Depends on #27517

This updates the Coder Agents platform controls documentation for the
per-template `agents_allowed` model. It replaces the deployment-wide
allowlist instructions with the **Agents allowed** controls in AI
Settings and template settings, documents that templates allow agents by
default, and explains that disabled templates are excluded from
`list_templates`, `read_template`, and `create_workspace`.

This is the final PR in the stack and aligns the template routing and
optimization guidance with the database, API, frontend, cleanup, and CLI
changes in the preceding PRs.
2026-08-07 17:23:28 +10:00
Jake Howell 7a9b4250aa refactor(site): demui <IconField /> (#27719)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

Replace MUI `TextField` / Emotion theming in `IconField` with
`InputGroup`, `Popover`, and Tailwind.

`IconPickerField` already had the demui'd `InputGroup` + `Popover`
implementation, so that was ported into the shared `IconField`. Per
review feedback, `IconPickerField` is now removed and its call sites
(the MCP server, provider, and OAuth app forms) use `IconField`
directly.
2026-08-07 09:56:05 +10:00
Samuel Volin 50640063a2 feat: DEVEX-732 premium badging (#27847)
Premium badging and gating consistency

as a OSS user, I want to be upsold to premium, and tastefully

Summary

Standardize all base-Premium full-page gates and the two named inline
notices. Admins see an in-app “Learn about Premium” path; non-admins are
told to contact their deployment administrator.
* DEVEX-732
* updates for premium docs pages for consistency
* updates for premium badging and paywall components
* updates implemented uses of premium badge and premiumpaywall


| Before | After |
| --- | ----------- |
| <img width="1271" height="564" alt="Screenshot 2026-08-04 at 3 02
32 PM"
src="https://github.com/user-attachments/assets/027d4bca-3e34-40b2-ad69-28dbaa4a004b"
/> | <img width="1273" height="600" alt="Screenshot 2026-08-04 at 3 26
37 PM"
src="https://github.com/user-attachments/assets/321083c0-7a4c-4c7e-a19c-059807018d3b"
/> |

| Before | After |
| --- | ----------- |
| <img width="1084" height="672" alt="image"
src="https://github.com/user-attachments/assets/741e6bd9-93b0-4ae0-97df-027e8aba5716"
/> | <img width="1289" height="622" alt="Screenshot 2026-08-04 at 3 20
07 PM"
src="https://github.com/user-attachments/assets/b3a8c169-ca6e-439b-8752-9209131fc097"
/> |

| Before | After |
| --- | ----------- |
| <img width="1091" height="865" alt="image (1)"
src="https://github.com/user-attachments/assets/f7cd92dd-a975-4db0-bc2a-af092ba783ce"
/> | <img width="1268" height="680" alt="Screenshot 2026-08-04 at 3 37
06 PM"
src="https://github.com/user-attachments/assets/8af8081a-0ec9-4fd3-921c-470127f2328b"
/> |
2026-08-06 12:13:12 -06:00
Andrew Aquino baed1455cf feat(site/src/pages/TemplateBuilder): scroll to module when clicking sidebar row (#27351)
## What

Clicking a selected module in the right-hand `SelectionSummary` sidebar
now jumps to the module settings step and scrolls that module's card
into view.

Addresses [DEVEX-587](https://linear.app/codercom/issue/DEVEX-587). This
is an isolated slice of #27077 (which bundles several unrelated
changes); only the "click a module to scroll to it" behavior is included
here.

## Changes

- `SelectionSummary`: gains an optional `onNavigateModule` prop. When
provided, each selected module row renders as an accessible `<button>`
(hover + focus-ring) labeled `Configure <name>`; otherwise rows stay
non-interactive.
- `ModuleSettingsStep`: each module card wrapper gets a stable
`id={module-config-<id>}` scroll anchor plus `scroll-mt-24` so the
sticky top nav does not cover the title.
- `TemplateBuilderPageView`: adds `navigateToModule`, which switches to
the module settings step and scrolls the target module into view once it
renders. If the module settings step is skipped (no configurable
variables), the click is a no-op.
- `SelectionSummary.stories`: adds a `NavigateModuleClick` interaction
story and updates `WithLongNameModule` to the new button semantics.

## Explicitly out of scope

The rest of #27077 is not included: gallery height/card clamp,
sensitive-var banner relocation, trash-icon removal wiring, the
scroll-past required-field highlight subsystem, and the broader
navigable-sidebar work (step labels, base-row navigation, back-stack
semantics).

## Testing

- `pnpm check` (biome) clean
- `pnpm lint:types` (tsc) clean
- `pnpm vitest run --project=unit src/pages/TemplateBuilder` — 46 pass
- `pnpm vitest run --project=storybook src/pages/TemplateBuilder` — 34
pass (incl. new `NavigateModuleClick`)

<details>
<summary>Implementation plan / decision log</summary>

### Goal

Open a new PR containing only the changes that satisfy DEVEX-587:
clicking a selected module in the right-hand `SelectionSummary` sidebar
should jump to the module settings step and scroll that module's card
into view.

### Base has moved since #27077

PR #27077 was cut against an older `main`. Today's `main` was
refactored:

- Steps are URL-driven; `steps.ts` already provides `StepId`, per-step
`group` (1/2/3), and `nearestVisible()`.
- `TemplateBuilderPageView` already has `navigateToStep(index: number)`
and a `useEffect` that resets window scroll on every `currentStep.id`
change.
- The sidebar no longer has a deselect ("X") button. The PR's
entanglement between "make row a nav button" and "move deselect to a
trash icon" therefore does not exist on current `main`, so module
navigation can be added without removing behavior and without pulling in
the trash-icon item.

So the isolated diff was written against current `main`, not reused
verbatim from the PR. It is smaller than the PR's own hunks and does not
include `maxReachedStep`, step-label navigation, or base-row navigation.

### Decisions

- Scope for this PR: module-row navigation only.
- Skipped-settings fallback: no-op. When no selected module exposes
configurable variables, the `module-settings` step is skipped and
clicking a module row does nothing (there is no card to scroll to).

### Scroll timing

`navigateToStep` triggers a window scroll reset via an existing effect
keyed on `currentStep.id`. To cooperate, `navigateToModule` stores the
target module id in a ref and a follow-up effect (declared after the
scroll-reset effect, so it runs second) calls `scrollIntoView` inside
`requestAnimationFrame` once `module-settings` has rendered. When
already on `module-settings`, it scrolls immediately.

### Follow-up (deferred): full navigable sidebar

Not part of this PR, documented for later. The remainder of #27077's
item #2, rebased onto current `main`:

- `onNavigateStep?: (stepId: StepId) => void` on `SelectionSummary`.
- Clickable step labels: `Base Template` -> `base-infra`, `Modules` ->
`module-select`, `Customizations` -> `customizations`.
- Clickable selected base-template row -> `base-parameters` (fall back
to `base-infra` when that step is skipped for the chosen base).
- Back-stack semantics via a `maxReachedStep` prop so steps at or below
the furthest-reached group stay `complete` and clickable even after
navigating backward, while strictly-higher groups render as inert
`upcoming`.
- `StepIndicator` and `BaseTemplateSelection` render as `<button>` when
a navigation handler is supplied, else stay inert.
- Stories: `NavigationClicks`, `BackwardNavigation`, and
`UpcomingStepsInert`.

</details>

---

Coder Agents generated, on behalf of @aqandrew.
2026-08-06 08:26:49 -07:00
dylanhuff-at-coder 9b27d12929 chore: forbid direct response body JSON decode in codersdk (#27859)
Add a ruleguard rule forbidding direct
`json.NewDecoder(res.Body).Decode(...)` on `*http.Response` in codersdk
packages, so new typed endpoints use `codersdk.ReadBodyAsJSON` and keep
returning structured errors for non-JSON bodies. The rule matches both
the chained call form and decoders assigned to a variable first.

Intentional raw-body paths carry documented `//nolint:gocritic`
exceptions: the 16 agent-direct HTTP decodes in
`workspacesdk/agentconn.go` route through a single `decodeAgentJSON`
helper (agent-direct over tailnet, so `ReadBodyAsJSON`'s reverse
proxy/SSO error guidance does not apply), and the Azure IMDS
attested-document decode in `agentsdk/azure.go` keeps an inline
exception.

The two `UseNumber` decoders in `licenses.go` are migrated to a new
`codersdk.ReadBodyAsJSONUseNumber`, so `coder licenses add/list` also
return structured errors for non-JSON bodies instead of `invalid
character '<' looking for beginning of value`.

Note for local verification: golangci-lint caches results, so run
`golangci-lint cache clean` after modifying `scripts/rules.go` or the
rule may silently not fire.

Final PR of the stack on #27804, #27857, and #27858. Refs #27044.


Stack plan

Inventory (full-tree audit): 280 migratable call sites across 47 files;
17 excluded (16 agent-direct HTTP sites in `workspacesdk/agentconn.go`,
1 Azure IMDS decode in `agentsdk/azure.go`).

1. **#27857** `refactor(codersdk): use ReadBodyAsJSON in typed
endpoints`: mechanical migration of all sites except `chats.go` (224
sites, 46 files).
2. **#27858** `refactor(codersdk): use shared error helpers in chat
endpoints`: migrate the 56 `chats.go` sites and consolidate the
duplicated `readRawBodyAsError`/`newResponseError` helpers onto the
shared `client.go` error path, with regression tests for the 409
usage-limit flow.
3. **#27859** `chore: forbid direct response body JSON decode in
codersdk`: ruleguard rule with documented exceptions for the intentional
raw-body paths, plus `ReadBodyAsJSONUseNumber` for the `licenses.go`
decoders.



Reviewed and updated by Coder Agents on behalf of @dylanhuff-at-coder.
2026-08-06 08:03:47 -07:00
Cian Johnston 4e2620d64f fix(coderd/x/chatd): classify bedrock credential errors as non-retryable (#27913)
When a Bedrock provider is misconfigured without authentication methods,
AWS credential resolution fails and AIBridge writes the error as a
plain-text HTTP 500. The fantasy adapter captures the body text in
`ProviderError.ResponseBody`, but `Error()` returns only the SDK
transport wrapper, not the body.

Signal patterns in `chaterror.Classify` checked only `err.Error()` (the
wrapper), missing the useful text in `structured.detail` (the body).
This caused permanent configuration errors to fall through to the
generic 500 rule with `retryable=true`, making the chat worker retry up
to 25 times.

Introduce `combinedText` (merging the wrapper with `structured.detail`)
and widen signal checks that have no dedicated status code to use it:
overloaded, auth, config, usage limit, and timeout patterns. The
deadline signal stays on `err.Error()` to avoid treating ambiguous body
text as a local context deadline. Add a "resolve aws credentials" config
pattern so credential resolution failures classify as config, not
generic.

> Generated by Coder Agents
2026-08-06 15:51:32 +01:00
Nick Vigilante 2d320de71e docs(docs/.style/style-guide): adopt STE-derived prose rules (#27852)
Stacked on #27849.

Incorporates the transferable rules from [ASD-STE100 Simplified
Technical English](https://www.asd-ste100.org/) (Issue 9, 2025) into the
prose style guide, with per-rule attribution to the source rule numbers.
STE is the controlled-language standard for aerospace maintenance
documentation; this PR adopts its procedure-level discipline and clarity
rules, not its controlled dictionary or grammar restrictions, which
target a different audience.

- New **Procedural writing** page: one instruction per step, condition
before instruction, 20-word step budget, "callouts inform, steps
instruct" (with the delete-the-callouts test), and warnings must state
the consequence.
- **Voice and tone**: sentence and paragraph budgets, verbs over noun
forms, one clear referent per pronoun, and an explicit acknowledgment of
the contractions trade-off for international readers.
- **Word choice**: one term per concept, anchored on the glossary.
- **Accessibility and inclusion**: the idioms rule now covers developer
figurative verbs (spin up, tear down, stand up).
- **README**: registers the new page and adds ASD-STE100 to the
third-party references.

All new rules are documentation-only (no Vale rule) because they need
editorial judgment rather than pattern matching.

---

🤖 Built with AI assistance.
2026-08-06 10:17:41 -04:00
Nick Vigilante aa039479ed docs: add style-guide rule against "whose" for non-person antecedents (#27866)
## What

Adds a Word choice entry to the docs style guide, **"Whose for people,
not things"**. It restricts "whose" to people and points writers to
"with", "where", or "that has" for inanimate objects and abstract
concepts, since "whose" implies personhood.

## Where

`docs/.style/style-guide/word-choice.md`, inserted right after **Phrasal
verbs and their noun forms**, the closest existing grammar/usage rule.
Formatting matches the surrounding entries: sentence-case H2, a
two-sentence rationale (one sentence per line), `**Do**` / `**Don't**`
blockquotes, and a documentation-only enforcement note.

## Rule

> "Whose" is the possessive of "who", so it implies the antecedent is a
person.
> When the antecedent is an inanimate object or an abstract concept,
prefer "with", "where", or "that has".

Example:

- Don't: A chat whose gateway records have been pruned reports no cost.
- Do: A chat with pruned gateway records reports no cost.

## Notes

- Docs-only change (Markdown under `docs/`, no CI or build config), so
it's out of scope for `/coder-agents-review`; the doc-check agent covers
docs-only PRs.
- The style-guide subpages are Vale-exempt, so no Vale rule ships with
this. The enforcement note reads "Documentation-only. No Vale rule.",
matching the other documentation-only entries.

Linear:
[DOCS-612](https://linear.app/codercom/issue/DOCS-612/style-guide-avoid-whose-for-non-person-antecedents)

> This PR was created with AI assistance (Coder Agents).
2026-08-06 10:00:44 -04:00
Jeremy Ruppel d9d6ce9ddf perf(coderd/rbac): build span role attributes only when recording (#27310)
`rbacTraceAttributes` materialized the subject's role names (one string
allocation per role) and was passed into every `Filter`, `Authorize`,
and `Prepare` span at creation time, so the O(roles) work ran even when
no tracer was recording. It also called `SafeRoleNames()` twice.

Replace it with `setRBACAttributes`, which attaches the same attributes
*after* the span is created and only when `span.IsRecording()` is true,
reading `SafeRoleNames()` once. Recorded spans are unchanged; untraced
and unsampled calls skip the per-role work.

This originated from #27309: once `/authcheck` checks are batched
through `rbac.Filter`, each below-threshold group paid the
role-attribute build for the `Filter` span *and* for every per-object
`Authorize` span, so the redundant per-call work showed up as extra
allocations per request.

## Benchmarks

`AMD EPYC 9575F`, `benchstat`, no tracer configured (exercises the
`IsRecording()==false` path).

**`BenchmarkRBACManyOrgs`** (general RBAC eval), before vs after: wall
time flat (geomean −0.04%), allocations strictly lower everywhere
(geomean B/op −0.52%; `Authorize` −1.0 to −1.3% B/op), no regressions.

**Authcheck path** (`BenchmarkAuthcheckGrouping`, #27309 vs #27310,
back-to-back): this change is an **allocation reduction and is
time-neutral**. On the endpoint (`Grouped`) path, per-request
allocations drop ~4-5% B/op at common org counts (1-10); on the pure
per-object path the reduction grows with org count (B/op −2.6% → −7.3%
at 100 orgs). Wall time is flat within noise: low-org deltas sit inside
this host's ±10-23% run-to-run variance, so no wall-time claim is made.

Net: same speed, less garbage per request, which also lowers GC pressure
under real concurrent load.

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

- The `Filter` span wraps the whole filtering routine (total latency +
`num_objects`); it is the valuable span and is kept. The costly part was
`rbacTraceAttributes`, not the span itself.
- `rbacTraceAttributes` was O(roles): it allocated a string per role for
the `subject_roles` attribute and called `SafeRoleNames()` twice. On
`Filter`'s below-threshold fallback it ran once for the `Filter` span
and again for each per-object `Authorize` span, so a group of N objects
paid N+1 builds vs the old loop's N. Benchmarks confirm this as real
per-call allocation; its wall-time cost is below the authcheck
benchmark's noise floor.
- Deferring attribute construction behind `IsRecording()` requires the
span object, so the three callsites moved from `StartSpan(ctx,
rbacTraceAttributes(...))` to `StartSpan(ctx)` then
`setRBACAttributes(span, ...)`. No spans were removed or renamed;
recorded output is identical.
- Tradeoff: when a span is not recording,
`subject_roles`/`num_subject_roles`/etc. are not computed. Unsampled
spans emit nothing anyway, so there is no observable output change.

</details>

---

Authored with Coder Agents.
2026-08-06 09:18:46 -04:00
Jeremy RuppelandSteven Masley 51a9aa1bfc perf(coderd): batch authcheck permissions via rbac.Filter (#27309)
`POST /api/v2/authcheck` evaluated every check with a full policy
evaluation in a serial loop. A subject in many organizations (100+)
produced hundreds of full evaluations, taking seconds on a cold cache
(DEVEX-608).

Group the checks by `(action, resource type)` and authorize each group
with the existing `rbac.Filter`, which amortizes a single partial
evaluation across the group once it is large enough. Each check is
wrapped in a small value struct that carries its response key, so
`Filter`'s returned subset maps back to keys by reading a field rather
than relying on element identity.

`Filter` now takes an explicit `prepareThreshold`; existing callers pass
the new `rbac.DefaultFilterThreshold` (10), and `checkAuthorization`
passes 50, above the ~35-group crossover measured for this workload, so
subjects with few objects of a given type keep the per-object path and
cannot regress.

## Stacking

This is stacked on top of #27244. `Filter` runs `Prepare` (partial
evaluation), and those residuals are only compact once #27244's
set-membership residuals land. On plain `main` the existing O(N)
residual fanout means batching can regress at high org counts, so this
change should land with or after #27244.

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

### Bottleneck

- `site/src/modules/permissions/organizations.ts` defines ~14 permission
checks per org; `organizationsPermissions()` flattens them across all
orgs into one `POST /api/v2/authcheck`. A 100-org request is ~1400
checks.
- `checkAuthorization` looped serially, calling `Authorizer.Authorize`
(full eval) once per check.
- The endpoint's `maxFetch = 10` only caps checks that carry a
`resource_id`, not total checks, so it does not bound this workload.

### Approach

- Group checks by `(action, resource type)` and run each group through
`rbac.Filter`, which does one partial evaluation (`Prepare`) and reuses
it across the group.
- Carry the response key as data in a small value struct implementing
`RBACObject()`, so allowed results map back to keys without pointer
identity:

  ```go
  type authorizeCheck struct {
      key    string
      object rbac.Object
  }
  func (c authorizeCheck) RBACObject() rbac.Object { return c.object }
  ```

- `Filter` takes a required `prepareThreshold int` (no functional
options). Generic callers pass `rbac.DefaultFilterThreshold = 10`;
`/authcheck` passes 50 because the measured crossover for this workload
is ~35 groups.

### Alternatives rejected

- **Bounded `errgroup` parallelism**: reduced wall time at high org
counts but not aggregate work (allocations flat). Discarded in favor of
reducing work via partial evaluation.
- **Symmetric-deny Rego simplification** (on the #27244 branch):
replacing the known-org deny-fold with symmetric `org := -1` /
`scope_org := -1` rules failed existing SQL-compile tests. A `-1`
known-org vote gated by `not org = -1` produces a negated membership
test over the unknown org id, which OPA emits as an unconvertible
support rule. #27244's fold (`member_allow - org_deny`, a positive
set-difference membership test) is therefore load-bearing, not
incidental.

</details>

---

Authored with Coder Agents.

---------

Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
2026-08-06 09:18:46 -04:00
Jeremy Ruppel 7e708b24ce perf(coderd/rbac): collapse org authorization to a set-membership test (#27244)
## Problem

Authorization for users who belong to many organizations is slow. On the
list <br>endpoints (`/api/v2/organizations`, `/users`, `/groups`) a user
in hundreds of <br>orgs saw multi-second page loads
<br>([DEVEX-608](https://linear.app/codercom/issue/DEVEX-608/performance-degrades-for-users-in-many-organizations-across-multiple)
<br>/ coder/coder#21890 / Pylon
[#2758](<https://github.com/coder/coder/issues/2758>)). This is
partial-evaluation bound: `rbac.Prepare` <br>scales with the number of
org-scoped roles the subject carries.

## Root cause

The known-org path in `check_org_permissions` indexed an N-entry vote
map by the <br>object's org id:

```rego
vote := allow_map[input.object.org_owner]
```

`input.object.org_owner` is unknown during partial evaluation. Indexing
a map by <br>an unknown key cannot reduce to a single expression, so OPA
emits one residual <br>query per org membership, and
`newPartialAuthorizer` then calls `PrepareForEval` <br>once per
residual, making `Prepare` O(N) in org count. The list endpoints
<br>intentionally use partial eval; the fan-out is in partial eval
itself.

## Change

Test the object's org id for membership in a set that is fully known at
<br>partial-evaluation time, so the query collapses to a single
<br>`organization_id = ANY(ARRAY[...])` residual instead of N residuals:

* The known-org clause only ever votes to allow, tested via
<br>`org_owner in org_ids_with_vote(role_org_votes, 1)`.
* Org-level denies are folded into the org-member level as a ground set
<br>difference (`member_allow - org_deny`), so the unknown org id
appears in only <br>one positive membership test and the decision never
branches on it.
* The per-org vote maps are computed once as memoized zero-arg rules
<br>(`role_org_votes`, `role_member_votes`, `scope_org_votes`,
<br>`scope_member_votes`) instead of through parametrized functions that
OPA <br>re-evaluates at every call site.
* `role_allow`/`scope_allow`, the `any_org` path, and full evaluation
are <br>unchanged in behavior.

Semantics are unchanged (see the equivalence argument below). The only
<br>representational change is that a denied known org's intermediate
`org` vote is <br>now `0` instead of `-1`, compensated by the set
difference and not observable in <br>the final `allow` decision.

## Results

Measured with `BenchmarkRBACManyOrgs` (added on `main` in
coder/coder#27270). Full tables: <br>[B/op and
allocs/op](<https://github.com/coder/coder/pull/27244#issuecomment-4984523720>).

* Residual queries: O(N) -> O(1).
* `Prepare` / `PrepareAndCompile` memory changes from < />quadratic
growth on `main` <br>(176 MiB, 7.08M allocs per op at 100 orgs) to
near-linear (6.5 MiB, 258k <br>allocs), a < />96% reduction at 100 orgs,
with similar wins in time.
* Memoizing the vote maps removed an early single-org regression: at 1
org <br>`Prepare` now allocates < />7% fewer bytes and < />9% fewer
objects than `main`.
* `Authorize` (full evaluation) memory is marginally higher (+1-8%,
largest at <br>1 org) and time-neutral. This is the inherent cost of the
set-membership form <br>that keeps partial evaluation from fanning out;
full evaluation builds an <br>allow set it would not otherwise need.
* `go test ./coderd/rbac/...` passes, including `TestAuthorizeDomain`
(full- vs <br>partial-eval equivalence) and the regosql suite.

A second, independent bottleneck remains (out of scope here): the vote
map is <br>still built in O(N^2) in `check_all_org_permissions`
<br>(`roles[_].by_org_id[org_id]` scans all roles per org). Fixing it
means <br>pre-merging roles' `by_org_id` into one org->perms map in the
OPA input, and is <br>tracked as a follow-up.

## Testing

* `OrgDenyBlocksMember` (`TestAuthorizeLevels`): an org-level deny
blocks a <br>member-allowed action on an owned in-org object, while a
clean org is allowed, <br>including an action-scoped deny.
* `ScopeOrgDenyBlocksMember` (`TestAuthorizeScope`): the same fold at
the scope <br>level.
* The shared harness covers full and partial evaluation and asserts the
partial <br>result compiles to SQL with zero support rules.

<details><summary>Decision log and equivalence argument</summary>

### Why not deny-via-set-membership

The first attempt expressed deny as a second set-membership clause (`:=
-1 if org_owner in deny_set`). That makes `org`/`scope_org`
multi-valued, and the `not org = -1` checks in
`role_allow`/`scope_allow` then cause OPA to emit a
`data.partial.__not__` support rule that regosql cannot compile
(`TestAuthorizeDomain/UserACLList` failed). It failed even when the deny
set was empty, purely because the `-1` clause exists.

### Why not deny-via-enumeration

A follow-up enumerated only the (usually empty) deny set. It compiled
and passed, but it branches on the unknown org id (one ground residual
per denied org), which violates the "do not branch on the unknown" rule
in `coderd/rbac/POLICY.md`.

### Final approach: allow-only + ground set difference

The known-org clause votes only to allow, and the org-level deny gate is
moved into the org-member level as `member_allow - org_deny`, a set
difference over fully-known sets. The unknown org id is used only in
positive `in` tests, so there is no enumeration, no negated membership,
and no branching on the unknown.

### Empty-set residual pruning

A naive set-membership left unsatisfiable residuals (`org_owner in
set()`) for levels with no matching permissions (e.g. the org level for
an org-member role, or scope-org for `ScopeAll`), each still costing a
`PrepareForEval`. Guarding each membership with a ground `count(...) >
0` lets OPA drop those branches, flattening the residual count across
org sizes.

### Memoized vote maps

Profiling the single-org path showed the cost was repeated function
evaluation: the parametrized helpers rebuilt the same vote map for the
org, member, and scope paths on every check. Hoisting the maps into
memoized zero-arg complete rules (which OPA evaluates once per query)
removed that overhead and eliminated the single-org `Prepare`
regression, while composition keeps the policy readable.

### Equivalence (known-org path, `site != -1`)

* A: original `org == 1` <=> `org_owner in org_allow` (unchanged).
* B: original `org != -1 and member == 1` <=> `org_owner not in org_deny
and org_owner in member_allow` <=> `org_owner in (member_allow -
org_deny)` = new `org_member == 1`.

The critical case (`org` denies, member allows): old blocks it via `not
org = -1`; new blocks it because `org_owner` is removed from
`member_allow - org_deny`. Same outcome. Deny-wins aggregation is intact
because `check_all_org_permissions` still nets an org to `-1` via
`to_vote`, landing it in `org_deny`.

</details>

---

This PR was generated by Coder Agents on behalf of @jeremyruppel.
2026-08-06 09:18:45 -04:00
Danielle Maywood f9047e5836 feat(site/src): reconcile chats-by-workspace cache across archive and watch paths (#27901)
Implements Phase 2 item 5 of the chats query architecture: by-workspace
cache reconciliation. Stacked on #27892; base branch
`feat/chat-search-invalidation`.

## Problem

`chatsByWorkspace` mappings (flat `Record<workspaceId, chatId>`, IDs
only, archived chats filtered server-side) go stale on
archive/unarchive, workspace binding changes, and watch events (FINDINGS
2.3). Because the client cannot re-derive archived state from the cached
map, the only correct repair for a stale mapping is synchronous removal
plus family invalidation.

## Fix

- New `removeChatFromChatsByWorkspace(queryClient, chatId)` in
`site/src/api/queries/chats.ts`: value-match removal across the
by-workspace family, reference-preserving when nothing is removed
(mirrors the `patchChatMessages` no-op pattern).
- `archiveChat.onSuccess` and the AgentsPageLayout archive-and-delete
`onSuccess` synchronously remove the mapping; the existing
`onSettled`/explicit invalidations then reconverge.
- Watch handler: `deleted` branch removes then invalidates
(remove-before-invalidate ordering); `created` root branch invalidates;
merge path invalidates behind a new `shouldInvalidateChatsByWorkspace`
predicate (`status_change`, `action_required` only; `created`/`deleted`
have their own branches, title/summary/diff/context events do not move
`updated_at` ordering); `onOpen` reconnect invalidates for convergence.
- `useChatToolInvalidations`: workspace-binding tool completion
(`create_workspace`) also invalidates by-workspace; this is the only
reconciliation path on the embed route.

## Confirmed exclusions

- No optimistic patch in `updateChatWorkspace.onMutate`; the awaited
`onSettled` invalidation already converges.
- No cancellation guard for the by-workspace family (Phase 2 item 9
territory).
- No `createChat` change (already invalidates); no ACL or pin changes.

## Known constraints

- Cascade archives remove only the event's own chat ID from the mapping;
per-family-member `deleted` events plus family invalidation repair the
rest.
- The REST `patchChat` workspace-rebind branch publishes no watch event
server-side, so cross-session manual rebinds converge only via the
acting session's `onSettled` or a WorkspacesPage remount; not fixable
client-side.

## Testing

- `chats.test.ts`: removal scoping and reference-preservation tests;
`it.each` wiring tests (archiveChat/unarchiveChat/updateChatWorkspace
onSettled, createChat onSuccess invalidate by-workspace);
synchronous-removal assertion for `archiveChat.onSuccess`; negative
assertions for `updateChatTitle` and `createChatMessage`.
- `AgentsPageLayout.test.ts`: exhaustive `ChatWatchEventKind` table for
`shouldInvalidateChatsByWorkspace`.
- `useChatToolInvalidations.test.tsx`: create_workspace regression test
extended with a seeded by-workspace bystander.

PR generated by Coder Agents.
2026-08-06 10:25:37 +01:00
Danielle Maywood 632eecc090 feat(site/src): reintroduce chat search cache invalidation (#27892)
Stacked on `feat/chat-cache-semantic-ops`.

## Bug

Chat search results (`chatSearch` queries) were never invalidated, so
the search dialog served stale results after archives, renames,
deletions, new chats, message edits, and watch-driven status changes.

## Fix

Reintroduces `invalidateChatSearches`, a prefix invalidation over the
module-private `chatSearchFamilyKey`, and wires it into:

- `chats.ts`: `archiveChat.onSettled`, `unarchiveChat.onSettled`,
`updateChatTitle.onSettled`, `editChatMessage.onSettled`,
`createChat.onSuccess`
- `useChatStore.ts`: `upsertCacheMessages` (unconditional; assistant
message bodies are indexed too) and `replaceCacheMessages`
- `AgentsPageLayout.tsx`: the `deleted` and root `created` watch
branches, the merge watch branch (gated by a new exported
`shouldInvalidateChatSearches` helper), the `has_unread` clearing
effect, the `onOpen` reconnect convergence, and
`archiveAndDeleteMutation.onSuccess`

The merge-branch gate only invalidates for search-affecting event kinds
(`title_change`, `status_change`, `diff_status_change`,
`action_required`). `summary_change`, `chat_summary_change`, and
`context_dirty` are excluded: stale `last_turn_summary` subtitles are
accepted until reconciliation lands.

## Backend constraint

Message bodies only enter full-text search via the dbpurge backfill
(`search_tsv` starts NULL and is populated every 10 minutes). Frontend
invalidation fixes removals, ordering, and rendered fields immediately,
but a chat that newly matches on message body will not appear until the
next backfill. This is a server-side eventual-consistency limit we
accept.

## Scope decisions (confirmed)

- No invalidation in `createChatMessage.onSuccess`: the send path
already routes through `useChatStore.upsertCacheMessages`; adding both
would double-invalidate every send.
- No invalidation for `pinChat`/`unpinChat`/`reorderPinnedChat`
(ordering-only, self-heals).
- ACL mutations out of scope.
- No coalescing/debouncing; that belongs to a later reconciler PR.

## Tests

- Prefix invalidation: multiple distinct `q` params invalidated,
bystanders (list, by-workspace, entity, messages, cost tree) untouched.
- Mutation wiring: settlement of `archiveChat`, `unarchiveChat`,
`updateChatTitle`, `editChatMessage`, and `createChat` invalidates a
seeded search key; `createChatMessage` asserted NOT to.
- `shouldInvalidateChatSearches` unit-tested over all
`ChatWatchEventKind` values.

PR generated by Coder Agents.
2026-08-06 10:25:36 +01:00
4b7494be72 feat: harden chat generation runtime instrumentation for billing (#27451)
Closes CODAGT-835

## Summary

`chat_messages.runtime_ms` becomes the billing source of truth for Coder
Agents runtime (summed hourly by #27312), but it was built for
debugging: the June refactor (#26270) silently stopped recording
tool-step runtime, compaction was never measured, and interrupted turns
lost their partial runtime entirely. This PR defines the billable
metric, closes the paths that dropped it, and documents the definition
where the data lives.

## The billable definition

**`runtime_ms` is the wall-clock duration of the model invocation that
produced the persisted message content**, measured from just before the
provider stream opens until it is fully consumed.

What counts:

- Assistant generation steps, in top-level and sub-agent chats
(sub-agents are ordinary chats on the same generation path).
- Compaction summarization calls, persisted on the compaction assistant
message (**new**).
- Interrupted attempts: the message-part episode's lifetime is persisted
on the partial assistant message committed by `FinishInterruption`, so
partial generation time survives interruption (**new**; measured via a
new `Buffer.EpisodeDuration`, which works even though the generation
goroutine and the interrupt task are different tasks).

What deliberately does not count (each is documented in code and docs):

- **Local tool execution.** Tool wall time includes idle waits, most
importantly `wait_agent` polling a sub-agent chat that already bills its
own model invocations; billing the batch would double count, and
excluding one tool from a concurrent batch's wall time is ill-defined.
Pre-refactor instrumentation did include tool time; this makes the
exclusion an explicit product definition instead of a silent regression.
- **Failed model calls whose output is discarded** (retried attempts,
terminal errors, content-filter refusals). They persist no content, so
they bill nothing; billing errs toward undercounting. Notably a
stream-silence timeout can burn 10 idle minutes before a retry, which
should not be billable "active generation". If product later wants
failed attempts billed, that needs a place to persist runtime on error
turns (`FinishError` inserts no rows today) and is a deliberate
follow-up, not instrumentation drift.
- **Ancillary calls that produce no chat messages** (title generation,
advisor, turn summaries) and all idle/parked time (`requires_action`,
queueing).

The definition is documented as `COMMENT ON COLUMN
chat_messages.runtime_ms` (migration 000551, surfacing as a Go doc
comment on `ChatMessage.RuntimeMs`), on
`chatloop.PersistedStep.Runtime`, in the chatd architecture doc, and in
the Spend Management docs page.

## Index for the hourly scan

None needed: `GetTotalChatMessageRuntimeMsInRange` (#27312) filters an
hour-wide `created_at` range, which the existing
`idx_chat_messages_created_at` b-tree already serves; the residual
`runtime_ms IS NOT NULL` filter applies to one hour of rows. A partial
index would add permanent write amplification for a query that runs once
an hour.

> [!NOTE]
> Migration 000551 is also claimed by #27312; whichever merges second
renumbers via `fix_migration_numbers.sh`.

## Tests

- End-to-end: the existing full-server generation test now asserts
`RuntimeMs.Valid` on the committed assistant row (it previously read
`.Int64` without checking `.Valid`, so it passed on NULL).
- Interrupted turn: full task-level test (real DB, mock clock) asserting
the partial assistant message persists the attempt's runtime.
- Errored stream: asserts a failed invocation yields no step and no
runtime.
- Tool-using turn: asserts runtime lands on the assistant row only and
tool rows stay NULL.
- Compaction: asserts the summarization call duration is recorded and
lands on the compaction assistant message only.
- `messagepartbuffer.EpisodeDuration` unit coverage.

Blocks: CODAGT-843 (B3), CODAGT-838 (D8).

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Hugo Dutka <hugo@coder.com>
2026-08-06 16:09:38 +07:00
Danielle Maywood f96671d588 refactor(site/src): centralize chat cache operations in semantic cache functions (#27869) 2026-08-06 08:29:10 +01:00
Jake Howell 3e0b943333 docs: note bulk stop confirmation (#27908)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

## What

Restores the docs change that was reverted out of #27631. The bulk
**Stop** action now shows a confirmation dialog (shipped in #27631), so
the workspace management docs should reflect that stop, alongside update
and delete, prompts for confirmation.

## How

Updates the Bulk operations section of
`docs/user-guides/workspace-management.md` to note that stop is now
included in the actions that prompt for confirmation before running.

<details>
<summary>Reverted change being restored</summary>

Before:

> For update and delete, the user will be prompted for confirmation
before any action is taken.

After:

> For update, delete, and stop, the user is prompted for confirmation
before any action is taken.

This content was originally added in #27631 (commit `e6a0aff`) and
reverted in commit `2378960` before merge.

</details>
2026-08-06 16:40:18 +10:00
dependabot[bot] abd330702b chore: bump the vite group across 1 directory with 4 updates (#27735)
Bumps the vite group with 4 updates in the /site directory:
[@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react),
[vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite),
[vite-plugin-checker](https://github.com/fi3ework/vite-plugin-checker)
and
[vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).

Updates `@vitejs/plugin-react` from 6.0.1 to 6.0.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/releases">@​vitejs/plugin-react's
releases</a>.</em></p>
<blockquote>
<h2>plugin-react@6.0.4</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>plugin-react@6.0.3</h2>
<p>No release notes provided.</p>
<h2>plugin-react@6.0.2</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md">@​vitejs/plugin-react's
changelog</a>.</em></p>
<blockquote>
<h2>6.0.4 (2026-07-22)</h2>
<h3>Fixed <code>$RefreshSig$ is not defined</code> error when running
<code>vite dev</code> with <code>NODE_ENV=production</code></h3>
<p>When running <code>vite dev</code> with
<code>NODE_ENV=production</code>, the app errored with
<code>$RefreshSig$ is not defined</code>.
This error is now fixed.</p>
<h2>6.0.3 (2026-06-23)</h2>
<h3>Improve the react compiler preset filter to reduce false-positives
(<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1138">#1138</a>)</h3>
<p>Improved the filter in the react compiler babel preset to reduce the
false-positives so that less modules are processed by the react
compiler.</p>
<h2>6.0.2 (2026-05-14)</h2>
<h3>Allow all options in reactCompilerPreset (<a
href="https://redirect.github.com/vitejs/vite-plugin-react/pull/1189">#1189</a>)</h3>
<p>This is a type only change. Only <code>compilationMode</code> and
<code>target</code> options were available for
<code>reactCompilerPreset</code>.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/f4b549822ec239799d746c030abb0b9a7d8f0a04"><code>f4b5498</code></a>
release: plugin-react@6.0.4</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/7a4065906e07e616aee23c4fcc76a76b74a7d694"><code>7a40659</code></a>
fix(react): <code>$RefreshSig$ is not defined</code> with
NODE_ENV=production vite dev ...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/98b32d47a3f2517d52e8a51d8e28ff2ed13678a2"><code>98b32d4</code></a>
fix(deps): update react 19.2.8 (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1298">#1298</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/8ae5449be23079dd17fdefc64064a3d94be6fc39"><code>8ae5449</code></a>
fix: babel-plugin-react-compiler cannot be imported when used in a
framework ...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/f09ea01b0b66a4900c3e42cef2aa0147e78b097c"><code>f09ea01</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1282">#1282</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/640fd358a0e82393acfce4e92e19a6ac6e1641a7"><code>640fd35</code></a>
release: plugin-react@6.0.3</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/889efb02cdc4ec978a5e177a37e0213cfded38a4"><code>889efb0</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1249">#1249</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/6c57dd4c5d71075b48039df2532804e72880da21"><code>6c57dd4</code></a>
fix(plugin-react): use '/' base in bundledDev preamble to fix non-root
base p...</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/3cc33a703636b558a1c1c99e787ddc6bd64aab2d"><code>3cc33a7</code></a>
fix(deps): update react-related dependencies (<a
href="https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react/issues/1245">#1245</a>)</li>
<li><a
href="https://github.com/vitejs/vite-plugin-react/commit/c0f7c7ff709dc9d88bc1f29f1b27c1b3e2bfcfca"><code>c0f7c7f</code></a>
docs: mention the Biome rule in the &quot;Consistent components
exports&quot; section (...</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.4/packages/plugin-react">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite` from 8.0.10 to 8.1.5
<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.1.5</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.5/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.4</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.4/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.3</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.3/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.2</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.2/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.1</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.1/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>create-vite@8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/create-vite@8.1.0/packages/create-vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>plugin-legacy@8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/plugin-legacy@8.1.0/packages/plugin-legacy/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>plugin-legacy@8.1.0-beta.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/plugin-legacy@8.1.0-beta.0/packages/plugin-legacy/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<h2>v8.1.0-beta.0</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v8.1.0-beta.0/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
<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.1.4...v8.1.5">8.1.5</a>
(2026-07-16)<!-- raw HTML omitted --></h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>bundled-dev:</strong> avoid duplicated <code>buildEnd</code>
(<a
href="https://redirect.github.com/vitejs/vite/issues/22931">#22931</a>)
(<a
href="https://github.com/vitejs/vite/commit/810032097079be1a7da0e2b09ec9d92dd07ec13f">8100320</a>)</li>
<li><strong>client:</strong> overlay error message format align rolldown
(<a
href="https://redirect.github.com/vitejs/vite/issues/22869">#22869</a>)
(<a
href="https://github.com/vitejs/vite/commit/5a72b8780705b575026617e86b0b92dea63a56a5">5a72b87</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22921">#22921</a>)
(<a
href="https://github.com/vitejs/vite/commit/fef682d3f067d534a559faf6fd9baedda2e9f8f1">fef682d</a>)</li>
<li><strong>deps:</strong> update rolldown-related dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22922">#22922</a>)
(<a
href="https://github.com/vitejs/vite/commit/3c345e475a5546a1cc6374682af89caebfe9c593">3c345e4</a>)</li>
<li><strong>module-runner:</strong> don't crash stack-trace source
mapping when globalThis.Buffer is absent (<a
href="https://redirect.github.com/vitejs/vite/issues/22945">#22945</a>)
(<a
href="https://github.com/vitejs/vite/commit/f8b38e316bcefbf29f762f90ee49c88cd52c43b5">f8b38e3</a>)</li>
<li><strong>optimizer:</strong> respect importer module format for
dynamic import interop with CJS deps (<a
href="https://redirect.github.com/vitejs/vite/issues/22951">#22951</a>)
(<a
href="https://github.com/vitejs/vite/commit/6c08c39ac4fb5868d080a51ff976a44693fc56ab">6c08c39</a>)</li>
<li><strong>ssr:</strong> scope switch-case declarations to the switch,
not the function (<a
href="https://redirect.github.com/vitejs/vite/issues/22893">#22893</a>)
(<a
href="https://github.com/vitejs/vite/commit/b59a73f76f5557492d83d097bb33b3dd02f27d51">b59a73f</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li><strong>build:</strong> fix incorrect <code>@default</code> for
build.cssMinify (<a
href="https://redirect.github.com/vitejs/vite/issues/22948">#22948</a>)
(<a
href="https://github.com/vitejs/vite/commit/c88c236186d8e2384653e382dd0960ca1ff5b24c">c88c236</a>)</li>
<li><strong>build:</strong> fix incorrect <code>@default</code> for
build.lib.formats (<a
href="https://redirect.github.com/vitejs/vite/issues/22911">#22911</a>)
(<a
href="https://github.com/vitejs/vite/commit/369ed609a4aace3aee4e4194a54990694aa4e7ac">369ed60</a>)</li>
</ul>
<h3>Tests</h3>
<ul>
<li>avoid scanner scanning all files under <code>__tests__</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22912">#22912</a>)
(<a
href="https://github.com/vitejs/vite/commit/c961cae2868cc1521457ec60583867f0440e6949">c961cae</a>)</li>
</ul>
<h2><!-- raw HTML omitted --><a
href="https://github.com/vitejs/vite/compare/v8.1.3...v8.1.4">8.1.4</a>
(2026-07-09)<!-- raw HTML omitted --></h2>
<h3>Features</h3>
<ul>
<li><strong>legacy:</strong> prefer oxc as minifier (fix <a
href="https://redirect.github.com/vitejs/vite/issues/21973">#21973</a>)
(<a
href="https://redirect.github.com/vitejs/vite/issues/22468">#22468</a>)
(<a
href="https://github.com/vitejs/vite/commit/ab5dafa8e66296ef201f615489fb57954bb740ce">ab5dafa</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>build:</strong> add workaround for building on stackblitz
(<a
href="https://redirect.github.com/vitejs/vite/issues/22840">#22840</a>)
(<a
href="https://github.com/vitejs/vite/commit/575c32c29925c554f4ef4068738ab89c6878f615">575c32c</a>)</li>
<li><strong>build:</strong> keep <code>import.meta.url</code> in preload
function as-is (<a
href="https://redirect.github.com/vitejs/vite/issues/22839">#22839</a>)
(<a
href="https://github.com/vitejs/vite/commit/f1f90ed4742b3cf453428c7e581a6016a4d47321">f1f90ed</a>)</li>
<li><strong>deps:</strong> update all non-major dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22865">#22865</a>)
(<a
href="https://github.com/vitejs/vite/commit/d4295a9ffce428c0e51892373e00c07fccc0498a">d4295a9</a>)</li>
<li><strong>deps:</strong> update rolldown-related dependencies (<a
href="https://redirect.github.com/vitejs/vite/issues/22866">#22866</a>)
(<a
href="https://github.com/vitejs/vite/commit/7cf07e4c5f7a6af276012e0c2ec06e08499e951e">7cf07e4</a>)</li>
<li><strong>html:</strong> avoid backtracking in import-only check (<a
href="https://redirect.github.com/vitejs/vite/issues/22848">#22848</a>)
(<a
href="https://github.com/vitejs/vite/commit/b5868c01a124d345664450aaebd677bfba964c05">b5868c0</a>)</li>
<li><strong>optimizer:</strong> avoid optimizer run for transform
request before init (<a
href="https://redirect.github.com/vitejs/vite/issues/22852">#22852</a>)
(<a
href="https://github.com/vitejs/vite/commit/72a5e2192506f51a5efd09c059815a5c43a9eacb">72a5e21</a>)</li>
<li><strong>ssr:</strong> align named export function call stacktrace
column with Node (<a
href="https://redirect.github.com/vitejs/vite/issues/22829">#22829</a>)
(<a
href="https://github.com/vitejs/vite/commit/173a1b648c321e0f836e5a94fc47c4fa9b081bfc">173a1b6</a>)</li>
<li>strip pure CSS chunk imports when chunkImportMap is enabled (<a
href="https://redirect.github.com/vitejs/vite/issues/22841">#22841</a>)
(<a
href="https://github.com/vitejs/vite/commit/648bd04933093d0aac9565f21a49811437776886">648bd04</a>)</li>
</ul>
<h3>Documentation</h3>
<ul>
<li>fix incorrect <code>@default</code> for <code>server.cors</code> (<a
href="https://redirect.github.com/vitejs/vite/issues/22859">#22859</a>)
(<a
href="https://github.com/vitejs/vite/commit/70435b2551ee4fe3a0d55c8a3bb61b96f44d2763">70435b2</a>)</li>
</ul>
<h3>Miscellaneous Chores</h3>
<ul>
<li><strong>deps:</strong> update dependency postcss-modules to v9 (<a
href="https://redirect.github.com/vitejs/vite/issues/22867">#22867</a>)
(<a
href="https://github.com/vitejs/vite/commit/a9539d69efc7a4ccf988bbf5da31c2b416ba990e">a9539d6</a>)</li>
</ul>
<h3>Code Refactoring</h3>
<ul>
<li>eliminate ineffectiveDynamicImport warn (<a
href="https://redirect.github.com/vitejs/vite/issues/22876">#22876</a>)
(<a
href="https://github.com/vitejs/vite/commit/ea22fb352aad9a42c0a9d08f39d8a0bae8c111a5">ea22fb3</a>)</li>
</ul>
<h3>Tests</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/5e7fe129a4dde4f41934083b25e490059985f4e6"><code>5e7fe12</code></a>
release: v8.1.5</li>
<li><a
href="https://github.com/vitejs/vite/commit/6c08c39ac4fb5868d080a51ff976a44693fc56ab"><code>6c08c39</code></a>
fix(optimizer): respect importer module format for dynamic import
interop wit...</li>
<li><a
href="https://github.com/vitejs/vite/commit/5a72b8780705b575026617e86b0b92dea63a56a5"><code>5a72b87</code></a>
fix(client): overlay error message format align rolldown (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22869">#22869</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/f8b38e316bcefbf29f762f90ee49c88cd52c43b5"><code>f8b38e3</code></a>
fix(module-runner): don't crash stack-trace source mapping when
globalThis.Bu...</li>
<li><a
href="https://github.com/vitejs/vite/commit/810032097079be1a7da0e2b09ec9d92dd07ec13f"><code>8100320</code></a>
fix(bundled-dev): avoid duplicated <code>buildEnd</code> (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22931">#22931</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/c88c236186d8e2384653e382dd0960ca1ff5b24c"><code>c88c236</code></a>
docs(build): fix incorrect <code>@default</code> for build.cssMinify (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22948">#22948</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/b59a73f76f5557492d83d097bb33b3dd02f27d51"><code>b59a73f</code></a>
fix(ssr): scope switch-case declarations to the switch, not the function
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22">#22</a>...</li>
<li><a
href="https://github.com/vitejs/vite/commit/fef682d3f067d534a559faf6fd9baedda2e9f8f1"><code>fef682d</code></a>
fix(deps): update all non-major dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22921">#22921</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/3c345e475a5546a1cc6374682af89caebfe9c593"><code>3c345e4</code></a>
fix(deps): update rolldown-related dependencies (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22922">#22922</a>)</li>
<li><a
href="https://github.com/vitejs/vite/commit/369ed609a4aace3aee4e4194a54990694aa4e7ac"><code>369ed60</code></a>
docs(build): fix incorrect <code>@default</code> for build.lib.formats
(<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/22911">#22911</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vitejs/vite/commits/v8.1.5/packages/vite">compare
view</a></li>
</ul>
</details>
<br />

Updates `vite-plugin-checker` from 0.13.0 to 0.14.5
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/fi3ework/vite-plugin-checker/releases">vite-plugin-checker's
releases</a>.</em></p>
<blockquote>
<h2>vite-plugin-checker@0.14.1</h2>
<h3>   🚨 Breaking Changes</h3>
<ul>
<li>Remove support for vue2/vls  -  by <a
href="https://github.com/danielroe"><code>@​danielroe</code></a> in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/708">fi3ework/vite-plugin-checker#708</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/bbf2aa3"><!--
raw HTML omitted -->(bbf2a)<!-- raw HTML omitted --></a></li>
<li><strong>deps</strong>: Update dependency chokidar to v5  -  in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/688">fi3ework/vite-plugin-checker#688</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/814f22b"><!--
raw HTML omitted -->(814f2)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>deps</strong>:
<ul>
<li>Update dependency tinyglobby to ^0.2.16  -  in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/693">fi3ework/vite-plugin-checker#693</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/198d23c"><!--
raw HTML omitted -->(198d2)<!-- raw HTML omitted --></a></li>
<li>Update react monorepo  -  in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/703">fi3ework/vite-plugin-checker#703</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/af01fd7"><!--
raw HTML omitted -->(af01f)<!-- raw HTML omitted --></a></li>
<li>Update dependency <code>@​babel/code-frame</code> to ^7.29.0  -  in
<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/702">fi3ework/vite-plugin-checker#702</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/9b0b81a"><!--
raw HTML omitted -->(9b0b8)<!-- raw HTML omitted --></a></li>
<li>Update dependency vue to ^3.5.32  -  in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/694">fi3ework/vite-plugin-checker#694</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/f673a4f"><!--
raw HTML omitted -->(f673a)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>eslint</strong>:
<ul>
<li>Lazily import eslint  -  by <a
href="https://github.com/danielroe"><code>@​danielroe</code></a> in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/709">fi3ework/vite-plugin-checker#709</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/83adffe"><!--
raw HTML omitted -->(83adf)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>oxlint</strong>:
<ul>
<li>File format not being found  -  by <a
href="https://github.com/H4ad"><code>@​H4ad</code></a> in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/714">fi3ework/vite-plugin-checker#714</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/3e4ab68"><!--
raw HTML omitted -->(3e4ab)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>tsc</strong>:
<ul>
<li>Force <code>noEmit</code> when <code>tsconfig.json</code> can't be
parsed  -  by <a
href="https://github.com/danielroe"><code>@​danielroe</code></a> in <a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/721">fi3ework/vite-plugin-checker#721</a>
<a
href="https://github.com/fi3ework/vite-plugin-checker/commit/590dcf5"><!--
raw HTML omitted -->(590dc)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/fi3ework/vite-plugin-checker/compare/vite-plugin-checker@0.13.0...vite-plugin-checker@0.14.1">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/5ab7cbb167453d35360ff24ddad718b827eec3f1"><code>5ab7cbb</code></a>
v0.14.5</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/bdd5c4d3b2333e98c259cca8c9656a15ddae811f"><code>bdd5c4d</code></a>
feat(eslint,stylelint,biome,oxlint): schedule lint runs across checkers
(<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/707">#707</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/4ebec51d0e7583d1e0a1e2b00c58278207ee23a2"><code>4ebec51</code></a>
fix(typescript): import absolute typescriptPath via file URL on
Windows</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/d33d281f134228c00ffc6c93e22ae39fdce3c2f2"><code>d33d281</code></a>
feat(typescript): add experimental support for TypeScript 7 (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/779">#779</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/7026910c9766e38bd53f37f3e4471df1608814d5"><code>7026910</code></a>
fix(oxlint): guard <code>runOxlint</code> against spawn errors (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/730">#730</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/e31fb72859d291464c8b2b83e2bc72324f68fd05"><code>e31fb72</code></a>
fix(eslint): fix path resolution for changed files (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/778">#778</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/15960c4e921de49615224572390e1767c26cc00a"><code>15960c4</code></a>
fix(checker): don't crash when a watched file is removed mid-lint (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/773">#773</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/132b9bdc98d1295777f4f5b762f5442066e15336"><code>132b9bd</code></a>
fix: emit un-based runtime specifier for virtual entry with custom base
(<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/782">#782</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/9ec07682ddaf9e5b684b3452f1d76da57942c2c3"><code>9ec0768</code></a>
chore(deps): update dependency lint-staged to v17.1.0 (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/772">#772</a>)</li>
<li><a
href="https://github.com/fi3ework/vite-plugin-checker/commit/5253f482323c2cb2ccf31a63a13eccc84a37206c"><code>5253f48</code></a>
chore(deps): update actions/cache digest to caa2961 (<a
href="https://redirect.github.com/fi3ework/vite-plugin-checker/issues/775">#775</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/fi3ework/vite-plugin-checker/compare/vite-plugin-checker@0.13.0...v0.14.5">compare
view</a></li>
</ul>
</details>
<br />

Updates `vitest` from 4.1.5 to 4.1.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">vitest's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.10</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Check fs access in builtin commands
[backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode
(claude-opus-4-8)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10680">vitest-dev/vitest#10680</a>
<a href="https://github.com/vitest-dev/vitest/commit/5c18dd267"><!-- raw
HTML omitted -->(5c18d)<!-- raw HTML omitted --></a></li>
<li><strong>vm</strong>: Fix external module resolve error with deps
optimizer query for encoded URI [backport to v4]  -  by <a
href="https://github.com/SveLil"><code>@​SveLil</code></a> and <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10661">vitest-dev/vitest#10661</a>
<a href="https://github.com/vitest-dev/vitest/commit/bae52b511"><!-- raw
HTML omitted -->(bae52)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10">View
changes on GitHub</a></h5>
<h2>v4.1.9</h2>
<h3>🐞 Bug Fixes</h3>
<ul>
<li>Fix <code>importOriginal</code> with optimizer and query import
[backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>David
Harris</strong>, <strong>Codex</strong>and <strong>Vladimir</strong> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10546">vitest-dev/vitest#10546</a>
<a href="https://github.com/vitest-dev/vitest/commit/a5180190c"><!-- raw
HTML omitted -->(a5180)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>:
<ul>
<li>Wait for orchestrator readiness before resolving browser sessions
[backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus
O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10555">vitest-dev/vitest#10555</a>
<a href="https://github.com/vitest-dev/vitest/commit/7fb29651a"><!-- raw
HTML omitted -->(7fb29)<!-- raw HTML omitted --></a></li>
<li>Wait for iframe tester readiness before preparing [backport to v4] -
by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10497">vitest-dev/vitest#10497</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10556">vitest-dev/vitest#10556</a>
<a href="https://github.com/vitest-dev/vitest/commit/fbc626c40"><!-- raw
HTML omitted -->(fbc62)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>mocker</strong>:
<ul>
<li>Hoist vi.mock() for vite-plus/test imports [backport to v4] - by
<strong>Hiroshi Ogawa</strong>, <strong>LongYinan</strong>,
<strong>Claude Opus 4.8</strong> and <strong>Vladimir</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10548">vitest-dev/vitest#10548</a>
<a href="https://github.com/vitest-dev/vitest/commit/2c9559c02"><!-- raw
HTML omitted -->(2c955)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>pool</strong>:
<ul>
<li>Prevent test run hang on worker crash [backport to v4] - by
<strong>Ari Perkkiö</strong> and <strong>Jattioui Ismail</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10543">vitest-dev/vitest#10543</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10564">vitest-dev/vitest#10564</a>
<a href="https://github.com/vitest-dev/vitest/commit/934b0f587"><!-- raw
HTML omitted -->(934b0)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5><a
href="https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9">View
changes on GitHub</a></h5>
<h2>v4.1.8</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>:
<ul>
<li>Disable client <code>cdp</code> API when <code>allowWrite/allowExec:
false</code> [backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10450">vitest-dev/vitest#10450</a>
<a href="https://github.com/vitest-dev/vitest/commit/e4067b3b1"><!-- raw
HTML omitted -->(e4067)<!-- raw HTML omitted --></a></li>
<li>Remove orphaned Playwright route when same module is mocked via
multiple ids [backport to v4]  -  by <a
href="https://github.com/toxik"><code>@​toxik</code></a> and <a
href="https://github.com/Zelys-DFKH"><code>@​Zelys-DFKH</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10474">vitest-dev/vitest#10474</a>
<a href="https://github.com/vitest-dev/vitest/commit/675b4343f"><!-- raw
HTML omitted -->(675b4)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8">View
changes on GitHub</a></h5>
<h2>v4.1.7</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>runner</strong>: Limit concurrency per task branch in
addition to per leaf callbacks (backport)  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10384">vitest-dev/vitest#10384</a>
<a href="https://github.com/vitest-dev/vitest/commit/4f0f2a1ee"><!-- raw
HTML omitted -->(4f0f2)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.6...v4.1.7">View
changes on GitHub</a></h5>
<h2>v4.1.6</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Provide project reference in
<code>ToMatchScreenshotResolvePath</code>  -  by <a
href="https://github.com/macarie"><code>@​macarie</code></a> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10138">vitest-dev/vitest#10138</a>
<a href="https://github.com/vitest-dev/vitest/commit/31882607c"><!-- raw
HTML omitted -->(31882)<!-- raw HTML omitted --></a></li>
<li>Global <code>sequence.concurrent: true</code> with top-level
<code>test(..., { concurrent: false })</code> + depreacte
<code>sequential</code> test API and options  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Codex</strong> and <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10196">vitest-dev/vitest#10196</a>
<a href="https://github.com/vitest-dev/vitest/commit/2847dfa2a"><!-- raw
HTML omitted -->(2847d)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>: Simplify orchestrator otel carrier  -  by
<a href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10285">vitest-dev/vitest#10285</a>
<a href="https://github.com/vitest-dev/vitest/commit/18af98cee"><!-- raw
HTML omitted -->(18af9)<!-- raw HTML omitted --></a></li>
</ul>
<h3>   🏎 Performance</h3>
<ul>
<li>Stringify diff objects only once  -  by <a
href="https://github.com/sheremet-va"><code>@​sheremet-va</code></a> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10276">vitest-dev/vitest#10276</a>
<a href="https://github.com/vitest-dev/vitest/commit/9f7b1528c"><!-- raw
HTML omitted -->(9f7b1)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.5...v4.1.6">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46"><code>db616d2</code></a>
chore: release v4.1.10 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10718">#10718</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/bae52b5112a6fd8200101b88bf8af9685d077295"><code>bae52b5</code></a>
fix(vm): fix external module resolve error with deps optimizer query for
enco...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4"><code>a7a61e7</code></a>
chore: release v4.1.9 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10598">#10598</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/934b0f587cb61d8338d83f525295322692a2db40"><code>934b0f5</code></a>
fix(pool): prevent test run hang on worker crash (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10543">#10543</a>)
[backport to v4] (#...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/7fb29651afbae2a9b0cefe6c031a9308f168ac60"><code>7fb2965</code></a>
fix(browser): wait for orchestrator readiness before resolving browser
sessio...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a5180190c1be7089e3705e3dd9e84fea118d09d3"><code>a518019</code></a>
fix: fix <code>importOriginal</code> with optimizer and query import
[backport to v4] (#...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e61f2dd2a0ba0a266c1c5e0334aad3799fee527f"><code>e61f2dd</code></a>
chore: release v4.1.8</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e4067b3b150005fd42cf75f994300119245806b9"><code>e4067b3</code></a>
fix(browser): disable client <code>cdp</code> API when
<code>allowWrite/allowExec: false</code> [ba...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a09d47236e19fd3151351080c667036ca6164dc4"><code>a09d472</code></a>
chore: release v4.1.7</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a8fd24c1cad2320b19fcc651413c7d928423bdc1"><code>a8fd24c</code></a>
chore: release v4.1.6</li>
<li>Additional commits viewable in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-06 04:57:44 +00:00
dependabot[bot] 8ebdc50b77 chore: bump @vitest/browser-playwright from 4.1.7 to 4.1.10 in /site (#27743)
Bumps
[@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright)
from 4.1.7 to 4.1.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitest-dev/vitest/releases">@​vitest/browser-playwright's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.10</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>: Check fs access in builtin commands
[backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a>,
<strong>Hiroshi Ogawa</strong> and <strong>OpenCode
(claude-opus-4-8)</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10680">vitest-dev/vitest#10680</a>
<a href="https://github.com/vitest-dev/vitest/commit/5c18dd267"><!-- raw
HTML omitted -->(5c18d)<!-- raw HTML omitted --></a></li>
<li><strong>vm</strong>: Fix external module resolve error with deps
optimizer query for encoded URI [backport to v4]  -  by <a
href="https://github.com/SveLil"><code>@​SveLil</code></a> and <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10661">vitest-dev/vitest#10661</a>
<a href="https://github.com/vitest-dev/vitest/commit/bae52b511"><!-- raw
HTML omitted -->(bae52)<!-- raw HTML omitted --></a></li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10">View
changes on GitHub</a></h5>
<h2>v4.1.9</h2>
<h3>🐞 Bug Fixes</h3>
<ul>
<li>Fix <code>importOriginal</code> with optimizer and query import
[backport to v4] - by <strong>Hiroshi Ogawa</strong>, <strong>David
Harris</strong>, <strong>Codex</strong>and <strong>Vladimir</strong> in
<a
href="https://redirect.github.com/vitest-dev/vitest/issues/10546">vitest-dev/vitest#10546</a>
<a href="https://github.com/vitest-dev/vitest/commit/a5180190c"><!-- raw
HTML omitted -->(a5180)<!-- raw HTML omitted --></a></li>
<li><strong>browser</strong>:
<ul>
<li>Wait for orchestrator readiness before resolving browser sessions
[backport to v4] - by <strong>Vladimir</strong> and <strong>Séamus
O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10555">vitest-dev/vitest#10555</a>
<a href="https://github.com/vitest-dev/vitest/commit/7fb29651a"><!-- raw
HTML omitted -->(7fb29)<!-- raw HTML omitted --></a></li>
<li>Wait for iframe tester readiness before preparing [backport to v4] -
by <strong>Vladimir</strong> and <strong>Séamus O'Connor</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10497">vitest-dev/vitest#10497</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10556">vitest-dev/vitest#10556</a>
<a href="https://github.com/vitest-dev/vitest/commit/fbc626c40"><!-- raw
HTML omitted -->(fbc62)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>mocker</strong>:
<ul>
<li>Hoist vi.mock() for vite-plus/test imports [backport to v4] - by
<strong>Hiroshi Ogawa</strong>, <strong>LongYinan</strong>,
<strong>Claude Opus 4.8</strong> and <strong>Vladimir</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10548">vitest-dev/vitest#10548</a>
<a href="https://github.com/vitest-dev/vitest/commit/2c9559c02"><!-- raw
HTML omitted -->(2c955)<!-- raw HTML omitted --></a></li>
</ul>
</li>
<li><strong>pool</strong>:
<ul>
<li>Prevent test run hang on worker crash [backport to v4] - by
<strong>Ari Perkkiö</strong> and <strong>Jattioui Ismail</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10543">vitest-dev/vitest#10543</a>
and <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10564">vitest-dev/vitest#10564</a>
<a href="https://github.com/vitest-dev/vitest/commit/934b0f587"><!-- raw
HTML omitted -->(934b0)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5><a
href="https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9">View
changes on GitHub</a></h5>
<h2>v4.1.8</h2>
<h3>   🐞 Bug Fixes</h3>
<ul>
<li><strong>browser</strong>:
<ul>
<li>Disable client <code>cdp</code> API when <code>allowWrite/allowExec:
false</code> [backport to v4]  -  by <a
href="https://github.com/hi-ogawa"><code>@​hi-ogawa</code></a> and
<strong>Codex</strong> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10450">vitest-dev/vitest#10450</a>
<a href="https://github.com/vitest-dev/vitest/commit/e4067b3b1"><!-- raw
HTML omitted -->(e4067)<!-- raw HTML omitted --></a></li>
<li>Remove orphaned Playwright route when same module is mocked via
multiple ids [backport to v4]  -  by <a
href="https://github.com/toxik"><code>@​toxik</code></a> and <a
href="https://github.com/Zelys-DFKH"><code>@​Zelys-DFKH</code></a> in <a
href="https://redirect.github.com/vitest-dev/vitest/issues/10474">vitest-dev/vitest#10474</a>
<a href="https://github.com/vitest-dev/vitest/commit/675b4343f"><!-- raw
HTML omitted -->(675b4)<!-- raw HTML omitted --></a></li>
</ul>
</li>
</ul>
<h5>    <a
href="https://github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8">View
changes on GitHub</a></h5>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46"><code>db616d2</code></a>
chore: release v4.1.10 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright/issues/10718">#10718</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/5c18dd267ff7f47f24cab2f615a16b37d90feb7f"><code>5c18dd2</code></a>
fix(browser): check fs access in builtin commands [backport to v4] (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright/issues/10680">#10680</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4"><code>a7a61e7</code></a>
chore: release v4.1.9 (<a
href="https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright/issues/10598">#10598</a>)</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e61f2dd2a0ba0a266c1c5e0334aad3799fee527f"><code>e61f2dd</code></a>
chore: release v4.1.8</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/675b4343fd82e094f0bed9c2b28489ce815f9c28"><code>675b434</code></a>
fix(browser): remove orphaned Playwright route when same module is
mocked via...</li>
<li><a
href="https://github.com/vitest-dev/vitest/commit/e4067b3b150005fd42cf75f994300119245806b9"><code>e4067b3</code></a>
fix(browser): disable client <code>cdp</code> API when
<code>allowWrite/allowExec: false</code> [ba...</li>
<li>See full diff in <a
href="https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/browser-playwright">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-06 04:46:36 +00:00
Ethan 78b5a0f5a2 feat(cli): add --agents-allowed to template commands (#27517)
Relates to CODAGT-713

Depends on #27515

This adds `--agents-allowed` to `coder templates create` and `coder templates edit`. Template creation defaults the option to true, matching the per-template API and database default, while template editing only changes the value when the flag is explicitly supplied so unrelated edits preserve the existing setting.

The generated CLI help and reference documentation include the new option. #27518 updates the Coder Agents platform controls documentation to describe the completed per-template model.
2026-08-06 14:45:38 +10:00
Jake Howell 6c8a8647f6 fix(site): name template versions in promote/archive dialogs and toasts (#27633)
> [!NOTE]
> These were previously returning as typed values in the `api.ts`,
however, they were not actually typed in this way and updating them
wouldn't have worked for the `promotion` as it would fall back to
needing to validate against the template.

Archive toasts showed `"undefined"` because the API does not return a
`TemplateVersion`. Toast/dialog copy now comes from the selected
version.

- Hold the full `TemplateVersion` for promote/archive confirms (global
pattern elsewhere)
- Name the version in confirm dialogs and success/error toasts
- Type archive/unarchive API helpers as `Promise<void>`

<img width="772" height="152" alt="image"
src="https://github.com/user-attachments/assets/0063ebdc-09a3-4041-bfa0-d4c70b57159b"
/>
2026-08-06 04:41:46 +00:00
dependabot[bot] 2484f4b047 chore: bump @tailwindcss/typography from 0.5.19 to 0.5.20 in /site (#27754)
Bumps
[@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography)
from 0.5.19 to 0.5.20.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss-typography/releases">@​tailwindcss/typography's
releases</a>.</em></p>
<blockquote>
<h2>v0.5.20</h2>
<h3>Fixed</h3>
<ul>
<li>Support installing with stable versions of Tailwind CSS v4 (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/pull/424">#424</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tailwindlabs/tailwindcss-typography/blob/main/CHANGELOG.md">@​tailwindcss/typography's
changelog</a>.</em></p>
<blockquote>
<h2>[0.5.20] - 2026-06-08</h2>
<h3>Fixed</h3>
<ul>
<li>Support installing with stable versions of Tailwind CSS v4 (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/pull/424">#424</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/e3714a3fe55551ce9d51eec4721183ed6b1d5cd1"><code>e3714a3</code></a>
0.5.20</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/f34283d2961e18dd0dc2a849702e0dfd45fc80cb"><code>f34283d</code></a>
Update tailwindcss peer dependency version (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/issues/424">#424</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/543de4274390e90c4aab5d216729b46a3ba5541b"><code>543de42</code></a>
bump Node.js</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/881b0488df9fd05e5361276b66a9ee8e7f39a3a7"><code>881b048</code></a>
Setup OIDC (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/issues/423">#423</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/74a3da779bb43e4e68f446395224c768704c1fb6"><code>74a3da7</code></a>
Fix typo in README.md (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/issues/413">#413</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/3963dfede4845f46451db1863fd5321f4cdea03b"><code>3963dfe</code></a>
Bump js-yaml from 3.14.1 to 3.14.2 (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/issues/410">#410</a>)</li>
<li><a
href="https://github.com/tailwindlabs/tailwindcss-typography/commit/abf85cc6e1b4f9b914b0f66453e5a97a9899a15c"><code>abf85cc</code></a>
className instead of classname (<a
href="https://redirect.github.com/tailwindlabs/tailwindcss-typography/issues/406">#406</a>)</li>
<li>See full diff in <a
href="https://github.com/tailwindlabs/tailwindcss-typography/compare/v0.5.19...v0.5.20">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 <code>@​tailwindcss/typography</code> 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>
2026-08-06 04:35:59 +00:00
Ethan d2f9280138 chore: remove legacy chat template allowlist (#27515)
Relates to CODAGT-713

Depends on #27514

Removes the legacy deployment-wide allowlist now that the API and frontend use per-template `agents_allowed`: the experimental `/template-allowlist` routes, SDK methods and generated types, site config queries, frontend bindings, and the now-unused `xjson` utility.

Migration `000563` deletes the obsolete `agents_template_allowlist` value. It's irreversible for deployments that configured an allowlist, which I think is fine, since `000562` already drops `agents_allowed` on the way down, and this release ships `000548` and `000555` with the same property.

Two side effects of the model change worth writing down, both from #27514 rather than here. The value used to need `ActionRead` on `ResourceDeploymentConfig` to read and deployment config update to write. `AgentsAllowed` is now a plain field on the template response, readable by anyone who can read the template, and it's set with a template update, so org admins manage it themselves. That's the delegation we wanted, and it's tracked in the audit log.

The rest of the stack adds `--agents-allowed` to the CLI and updates the platform controls docs.
2026-08-06 14:35:37 +10:00