Commit Graph
14248 Commits
Author SHA1 Message Date
Thomas Kosiewski 38091f1d82 fix(site/src/pages/AgentsPage/components/ChatConversation): remove attachment copy actions (#25119)
Messages with chat file attachments showed a `Copy message` action even
though the action only copied `parsed.markdown` and omitted the
attachment content.

Hide the message copy action whenever a parsed message contains file
attachments, and add regression coverage for both user and assistant
attachment messages.

Refs
https://linear.app/codercom/issue/CODAGT-344/remove-or-fix-copy-buttons-on-file-attachments

Generated by Coder Agents.
2026-05-12 15:46:39 +02:00
Atif Ali 97ee54a8c1 fix(site): clarify deleted workspace actions (#25186)
## Summary
Updates the deleted workspace banner so its CTA recreates from the
original template instead of sending users to the generic templates
list.

## Changes
- Change the CTA to `Create another from <template>`.
- Link the CTA to the original template workspace create flow.
- Shorten the banner copy to `This workspace has been deleted.`

## Validation
- `pnpm exec biome check --error-on-warnings
src/pages/WorkspacePage/Workspace.tsx
src/pages/WorkspacePage/WorkspaceDeletedBanner.tsx
src/pages/WorkspacePage/WorkspaceDeletedBanner.stories.tsx`
- `pnpm run lint:types`
- `git diff --check`
- `git commit` pre-commit hooks

> 🤖 This PR was created with the help of Coder Agents, and needs a human
review. 🧑💻
2026-05-12 18:45:20 +05:00
Ben Potter cc001ccaf0 docs(docs/ai-coder/ai-gateway/clients): fix enable_aibridge -> enable_ai_gateway (#25098)
The Claude Code and Codex CLI registry modules expose the variable as
`enable_ai_gateway`, not `enable_aibridge`. Templates using the docs as
written fail Terraform init with `An argument named "enable_aibridge" is
not expected here.`

Verified in
[`registry/coder/modules/claude-code/main.tf`](https://github.com/coder/registry/blob/main/registry/coder/modules/claude-code/main.tf)
and
[`registry/coder-labs/modules/codex/main.tf`](https://github.com/coder/registry/blob/main/registry/coder-labs/modules/codex/main.tf),
where the variable is declared as `enable_ai_gateway` and gates the
`ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN` injection.

_Generated with the help of Coder Agents._
2026-05-12 08:18:41 -05:00
Michael Suchacz 96333acda3 fix(coderd): filter build instance agents in SQL (#25031)
Replaces the per-agent Go-side template-version filter in
`handleAuthInstanceID` with a purpose-built SQL query.

`GetWorkspaceBuildAgentsByInstanceID` joins `workspace_agents ->
workspace_resources -> workspace_builds -> provisioner_jobs ->
workspaces` and excludes:

- non-`workspace_build` provisioner jobs (template-version-import,
dry-run)
- deleted agents and sub-agents
- deleted workspaces

The handler:

- drops the per-candidate `GetWorkspaceResourceByID` /
`GetProvisionerJobByID` lookups
- drops the `provisioner_jobs.input` JSON parsing and the follow-up
`GetWorkspaceBuildByID` call
- compares `latestHistory.ID` against `selected.WorkspaceBuildID`
returned directly from the query
- preserves the existing recycled-instance safety check and matching
response codes

One intentional behavior tightening: agents whose workspace is deleted
now return 404 (previously they could reach the recycled-instance check
and return 400, or 200 if the stale build was still latest). This
matches the existing token-auth path, which already refuses to
authenticate against deleted workspaces.

The original `GetWorkspaceAgentsByInstanceID` query is intentionally
untouched. It remains the generic raw lookup used elsewhere in tests and
helpers.

The dbauthz wrapper for the new query uses the system-read fast path
with `fetchWithPostFilter` for non-system reads, with `RBACObject()`
delegating to the embedded `WorkspaceTable`.

Tests:

- new `TestGetWorkspaceBuildAgentsByInstanceID` covering newest-first
ordering, exclusion of deleted/sub agents, exclusion of template-import
and dry-run jobs, and exclusion of deleted workspaces
- new dbauthz mock test for `GetWorkspaceBuildAgentsByInstanceID`
- new `TestPostWorkspaceAuthAWSInstanceIdentity/RecycledInstanceID`
exercising the recycled-instance rejection branch (HTTP 400 when the
agent's build is no longer latest)
- existing `TestPostWorkspaceAuth{AWS,Azure,Google}InstanceIdentity`
continue to cover the handler end to end (including the template-version
+ workspace-build same-instance-ID scenario via
`setupInstanceIDWorkspace`)

> Mux is acting on Mike's behalf.
2026-05-12 14:55:56 +02:00
Kyle Carberry b0b07536fc feat: add opt-in Coder identity headers for MCP servers (#25153) 2026-05-12 08:54:53 -04:00
Michael Suchacz f1d160c7f4 fix: allow changing model when editing earlier chat message (#25084)
Editing a previous user message and selecting a different model in the
picker silently kept using the original model: the selection was dropped
on the frontend, in the SDK, and in the backend, so both the replacement
user message and the assistant turn that followed ran against the old
model.

Plumb the selected model through all three layers (`AgentChatPage`,
`codersdk.EditChatMessageRequest`, `chatd.EditMessageOptions` /
`Server.EditMessage`), defaulting to the original message's model when
the client does not specify one. The existing `InsertChatMessages` CTE
already advances `chats.last_model_config_id` when the inserted
message's model differs, so the assistant turn picks up the new
selection without further changes. The new model is validated inside the
transaction, so an unknown ID rolls the edit back and returns a 400
`Invalid model config ID.`, mirroring the `SendMessage` path.

Refs: CODAGT-345

This change was generated by a Coder agent.

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

# CODAGT-345: Editing an earlier message cannot change model

## Problem

When editing a previous user message in a chat, the user can change the
model in the model picker, but the backend keeps using the original
message's model. The model selection is dropped at three layers:

1. **Frontend:** `AgentChatPage.tsx`'s edit branch builds an
`EditChatMessageRequest` that omits `model_config_id`. The new-message
branch (a few lines below) does include it.
2. **SDK:** `codersdk.EditChatMessageRequest` has no `ModelConfigID`
field at all.
3. **Backend:** `chatd.EditMessageOptions` has no model field, and
`Server.EditMessage` always copies the original message's
`ModelConfigID` into the replacement message.

Once the replacement user message is inserted with the original model,
the `InsertChatMessages` CTE leaves `chats.last_model_config_id`
unchanged, so the assistant turn that follows runs against the old
model.

## Fix

Plumb the selected model through all three layers, defaulting to the
original message's model when the client doesn't override it. This
mirrors the `SendMessage` path, which already accepts a
`model_config_id` and validates it via
`resolveSendMessageModelConfigID`.

### Backend

- `codersdk/chats.go`: add `ModelConfigID *uuid.UUID` to
`EditChatMessageRequest`.
- `coderd/x/chatd/chatd.go`:
  - Add `ModelConfigID uuid.UUID` to `EditMessageOptions`.
- In `EditMessage`, after fetching the edited message, resolve the
model: if `opts.ModelConfigID != uuid.Nil`, validate it exists with
`tx.GetChatModelConfigByID` (using `chatdModelConfigLookupContext`),
otherwise keep `editedMsg.ModelConfigID.UUID`. Pass the resolved ID into
`newChatMessage(...)`.
  - Reuse the existing `ErrInvalidModelConfigID` sentinel.
- `coderd/exp_chats.go` (`patchChatMessage`):
- Read `req.ModelConfigID` (nil-safe), pass into
`chatd.EditMessageOptions`.
- Add a `case xerrors.Is(editErr, chatd.ErrInvalidModelConfigID)` arm
returning 400 `Invalid model config ID.`, matching the
`postChatMessages` handler.

### Frontend

- `site/src/pages/AgentsPage/AgentChatPage.tsx`:
- In the edit branch, set `model_config_id: effectiveSelectedModel ||
undefined` on the `EditChatMessageRequest`.
- On success, persist the chosen model to `lastModelConfigIDStorageKey`
so the next chat from this browser keeps the same default. Mirrors the
new-message branch.

### Generated

- `make site/src/api/typesGenerated.ts` and `make
coderd/apidoc/swagger.json` produce the updated `EditChatMessageRequest`
schema in `typesGenerated.ts`, `coderd/apidoc/{docs.go,swagger.json}`,
and `docs/reference/api/{chats.md,schemas.md}`.

## Tests

- `coderd/x/chatd/chatd_test.go`:
- `TestEditMessageWithModelConfigOverride`: edit with a different model
-> replacement message and `chats.LastModelConfigID` use the new model.
- `TestEditMessagePreservesModelConfigByDefault`: edit without
`ModelConfigID` -> original model preserved.
- `TestEditMessageRejectsUnknownModelConfig`: passes a random UUID ->
`ErrInvalidModelConfigID`, original message still present,
`LastModelConfigID` unchanged (rollback).
- `coderd/exp_chats_test.go` (under `TestPatchChatMessage`):
- `ChangesModel`: end-to-end via SDK; `edited.Message.ModelConfigID` and
`chat.LastModelConfigID` both match the new model.
- `InvalidModelConfigID`: random UUID -> 400 `Invalid model config ID.`.

</details>
2026-05-12 14:51:55 +02:00
Michael Suchacz f847ff3731 test(coderd/x/chatd): skip stale notification flakes (#25177)
Skip the chatd tests that currently flake because the control
notification flow cannot distinguish stale wake/status NOTIFY payloads
from real interrupt requests. Each skipped test includes a TODO to
re-enable it after the chatd notification flow refactor handles stale
notifications correctly.

Supersedes #25133, #25134, #25135, and #25139.

Refs [CODAGT-353](https://linear.app/coder/issue/CODAGT-353),
[CODAGT-356](https://linear.app/coder/issue/CODAGT-356),
[CODAGT-360](https://linear.app/coder/issue/CODAGT-360), and
[CODAGT-361](https://linear.app/coder/issue/CODAGT-361).

> Mux working on behalf of Mike.
2026-05-12 14:50:30 +02:00
Ethan 4e08543ace test(coderd): centralize chat test harness and stabilize flakes (#25171)
Chat tests previously constructed a real `openai` provider with a fake
API key and no `BaseURL`, so background title generation hit
`api.openai.com` and timed out under `-race`. The same root cause
produced several distinct flakes: title regeneration races with
synchronous `UpdateChat`/`ProposeChatTitle`, and pagination races
against `updated_at` bumps from real-network processing.

This moves the fake OpenAI-compatible provider and the chat-settle wait
into first-class `coderdtest` capabilities.
`coderd.Options.ChatProviderAPIKeys` is the new seam tests use to
redirect chat traffic to a local `httptest.Server`.
`coderdtest.WaitForChatSettled` replaces per-test waiters and drains
tracked chat-daemon work after the chat row leaves `pending`/`running`.
The `newChatClient*` constructors funnel through one options builder
that installs the fake provider before the coderd test server so cleanup
ordering is deterministic.

Closes https://github.com/coder/internal/issues/1528 & Closes ENG-2659
Closes https://github.com/coder/internal/issues/1480 & Closes CODAGT-359
Closes https://github.com/coder/internal/issues/1507 & Closes CODAGT-368
Relates to https://github.com/coder/internal/issues/1397 & Relates to
CODAGT-374
2026-05-12 22:13:55 +10:00
Jaayden Halko 8ba24e0e54 feat(site): add collapsible agent sections (#25173)
closes CODAGT-395

<img width="426" height="480" alt="Screenshot 2026-05-12 at 19 04 03"
src="https://github.com/user-attachments/assets/ba336ecf-3e90-48b0-b5d3-b10499909953"
/>

Adds collapsible section headers to the Agents sidebar, including
visible counts and chevrons for pinned and time-grouped chats.

The section header toggle keeps nested chat expansion state independent,
preserves the existing filter dropdown behavior, and adds Storybook
coverage for counts, collapse or expand interactions, and filter menu
behavior.
2026-05-12 13:07:57 +01:00
Danielle Maywood a55430b8fd fix(site/src/pages/AgentsPage): suppress last-message spacer during active stream (#25120) 2026-05-12 12:31:40 +01:00
Cian Johnston caabb3c4ab fix(site): show Organizations in admin dropdown for single-org OSS deployments (#25175)
Fixes https://linear.app/codercom/issue/CODAGT-350

On OSS or no-license single-org deployments, the Organizations admin
link was hidden because `canViewOrganizationSettings` was gated on
`showOrganizations`, which requires either a multi-org entitlement or >1
org. The page was still reachable via direct URL, but the members view
displayed a raw "Template RBAC is a Premium feature. Contact sales!"
error from the groups API.

Two fixes:

1. Always render the Organizations link inside the `DeploymentDropdown`.
The dropdown itself is only shown to users with admin-level permissions,
so Organizations is effectively gated on having admin access.

2. Remove `groupsByUserIdQuery.error` from the error chain on the
members page. The groups endpoint is gated behind
`templateRBACEnabledMW` on enterprise, returning a 403 on OSS. The
groups data is already optional, so the page renders fine without it.

> Generated by Coder Agents
2026-05-12 12:28:43 +01:00
Thomas Kosiewski 5c3b59151e feat: add Cmd/Ctrl+Enter send setting (#25062)
Adds an Agents General setting to require Cmd/Ctrl+Enter before sending
chat messages. When enabled, plain Enter inserts a newline in agent chat
inputs while the send button remains available.

The preference is now persisted server-side through
`/api/v2/users/{user}/preferences`, alongside the existing user
preference settings, and is applied to both the create-agent input and
existing chat composer. Storybook and API coverage verify the setting,
keyboard behavior, validation, and persistence.

<details>
<summary>Coder Agents notes</summary>

Generated by Coder Agents from a Slack request. Dogfooded with
agent-browser against the Storybook settings and chat input stories.

</details>
2026-05-12 10:09:34 +02:00
Kyle Carberry 376fc80451 fix(coderd/x/chatd): discover workspace MCP tools mid-turn after create_workspace (#25169)
## Problem

In `coderd/x/chatd/chatd.go` `runChat`, workspace MCP discovery is gated
on `chat.WorkspaceID.Valid` at the start of each turn. New chats that
bind their workspace mid-turn (via `create_workspace` or
`start_workspace`) get an empty workspace tool list on the first step,
and the model falls back to `execute` (bash) because no workspace MCP
tools are advertised.

**Repro:** new chat → "create a workspace and use MCP tools". No
`/api/v0/mcp/tools` request hits the agent on turn 1; turn 2 in the same
chat works fine.

## Fix

- Add a `PrepareTools` callback to `chatloop.RunOptions`, analogous to
`PrepareMessages`. It is invoked once before each LLM step with the
current tool list. When it returns non-nil, the chatloop replaces
`opts.Tools`, rebuilds the per-step tool definitions, and appends new
tool names to `opts.ActiveTools` so newly injected tools are callable
immediately.
- Wire `PrepareTools` in `runChat` to trigger workspace MCP discovery
the first time the chat snapshot reports a valid `WorkspaceID`. The
previous top-of-turn discovery path is unchanged for chats that start
with a workspace.
- Extract the discovery logic into `Server.discoverWorkspaceMCPTools` so
the top-of-turn and mid-turn paths share identical behavior (cache,
agent resolution, `ListMCPTools` timeout, invalidation).

Mid-turn discovery stays disabled in plan-mode turns and Explore
subagents, matching the existing top-of-turn gate. The
`workspaceMCPDiscovered` flag prevents redundant dials after the first
successful discovery.

## Tests

- `coderd/x/chatd/chatloop/chatloop_test.go`: two new
`TestRun_PrepareTools*` cases covering injection on the next step and
active-set merging when `ActiveTools` is non-empty.
- `coderd/x/chatd/chatd_test.go`:
`TestRunChat_WorkspaceMCPDiscoveryAfterMidTurnCreateWorkspace` drives
`runChat` through a `create_workspace` tool call against a real Postgres
+ mocked agent conn and asserts the second streamed LLM request
advertises the workspace MCP tool. Verified that the test fails (and
pinpoints the missing tool) when the `PrepareTools` wiring is disabled.

## Validation

```
go test ./coderd/x/chatd/chatloop/... -count=1
go test ./coderd/x/chatd/... -count=1
make lint/emdash
```

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

- Chose a per-step `PrepareTools` callback over mutating `opts.Tools` in
place because `chatloop.Run` builds the `fantasy.Tool` definitions once
at start; a hook is required to let the LLM see new tools on the next
step.
- Returned `[]fantasy.AgentTool` (not also active-tool-names) and let
the chatloop derive name merges via `mergeNewToolNames`. This avoids
leaking plan-mode gating decisions into the callback contract.
- Kept the existing top-of-turn discovery path so chats that already
have a workspace at turn start pay no extra latency.
- Skipped reusing `ReloadMessages` (history reload) since this is purely
a tool-availability concern; coupling it to a history reload would
defeat the chatloop cache prefix optimizations.

</details>

---

_This pull request was generated by Coder Agents._
2026-05-12 00:30:56 -04:00
Kyle Carberry 5a5cd79c4c fix: drop buffered chat parts after their durable message commits (#25164) 2026-05-12 00:30:38 -04:00
Kyle Carberry 07ff3b3f90 fix(coderd/exp_chats_test.go): stabilize TestListChats/Pagination by inserting chats directly (#25137) 2026-05-12 00:26:22 -04:00
Kayla はな d8ca626aec chore(dogfood): use default rustup profile (#25165) 2026-05-11 19:47:49 -06:00
Yevhenii Shcherbina 592e45dcfb chore: bump coder-guts dependency (#25154)
Bump coder/guts to v1.7.0.
Related PR: https://github.com/coder/guts/pull/81
2026-05-11 19:18:44 -04:00
Michael Suchacz 7a7b196b21 fix(site/src/pages/AgentsPage/components/Sidebar): keep subtitle in sync during streaming lifecycle (#25144)
The Agents sidebar shows the per-chat turn-end summary as a subtitle,
but the cached `last_turn_summary` is not always in sync with the live
status:

- **Resuming a turn**: when a chat goes back to `running` or `pending`,
the sidebar would keep displaying the previous turn-end label (e.g.,
"Chat is idle") while the agent is already streaming again.
- **Stream end → next summary**: status flips to `waiting`
synchronously, but the new `last_turn_summary` is generated by an async
finalizer that calls the model. For a beat, the row still carries the
previous turn's summary text, which would briefly flash before the new
text arrives.

This PR addresses both:

1. Override the subtitle with `{model} streaming…` while `chat.status`
is `running` or `pending`, matching the same `isStreaming` definition
`ChatPageContent` uses. Errors still take precedence so failure context
is not hidden.
2. Capture the cached summary observed during streaming and suppress an
exact match on the post-stream renders until the new summary lands.
State is adjusted during render so the first post-stream paint already
hides the stale string instead of flashing it for a frame. A 10s timeout
safety net releases the suppression in the corner case where the
regenerated summary equals the previous one byte-for-byte.

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

- **Frontend-only fix**: the server intentionally does not bump
`updated_at` when it writes the new `last_turn_summary` (see
`UpdateChatLastTurnSummary` in `coderd/database/queries/chats.sql`), and
SSE delivers the status flip ahead of the new label. The sidebar knows
the live status, so the rendering layer is the right place to mask the
inconsistency.
- **`isStreaming = running || pending`** mirrors `ChatPageContent.tsx`
so subagents and queued continuations also flip to the live label.
- **State, not refs**, for the suppression bookkeeping: the React
Compiler rejects ref writes during render, and React's "adjust state
during render" pattern is purpose-built for storing information from
previous renders (state setters in render bail out and re-render
synchronously before paint).
- **10s timeout** is a safety net for the rare byte-for-byte equality
case; the equality-based release handles every other shape of update.
- Added Storybook stories covering both fixes
(`ChatStreamingOverridesTurnSummary` and
`StaleTurnSummaryAfterStreamingIsSuppressed`). All existing legacy
subtitle stories still pass because they use terminal statuses.

</details>

> This PR was created by Coder Agents on behalf of @ibetitsmike.
2026-05-12 00:51:22 +02:00
Garrett DelfosseandZach 566dace1bc fix(scripts/releaser): use last stable release as changelog base for .0 releases (#24988)
When releasing a `.0` version (e.g. `v2.33.0`) from a release branch,
the release notes diff was comparing against the most recent RC (e.g.
`v2.33.0-rc.3`) instead of the last stable release from the previous
minor series (e.g. `v2.32.X`).

## The bug

`prevVersion` is set to the latest tag matching the branch's
`major.minor` from merged tags. For a `.0` release, this is the latest
RC (e.g. `v2.33.0-rc.3`). The commit range for release notes then
becomes `v2.33.0-rc.3..HEAD` instead of `v2.32.X..HEAD`, so the notes
only show the delta from the last RC rather than all changes since the
previous real release. The compare link also points to
`v2.33.0-rc.3...v2.33.0`.

## The fix

After all semver sanity checks have run (so version suggestion and
validation are unaffected), when the new version is a `.0` release and
`prevVersion` is an RC, override `prevVersion` with the last stable
release from the previous minor series. This makes both the commit range
and compare link use the correct base (e.g. `v2.32.X..HEAD` and
`v2.32.X...v2.33.0`).

> Generated with [Coder Agents](https://coder.com/agents)

---------

Co-authored-by: Zach <3724288+zedkipp@users.noreply.github.com>
2026-05-11 22:18:09 +00:00
Michael Suchacz bb8c40e764 feat: stream go test failure summary and drop raw json artifact (#25146)
This follows up on
https://github.com/coder/coder/actions/runs/25684936801/job/75406131184?pr=25139
by replacing the large raw Go test JSON artifact with inline structured
summaries and a compact failures-only artifact.

## What changed

- Added `scripts/gotestsummary`, a streaming Go tool that reads
gotestsum JSON and renders failed tests as Markdown.
- Updated the three Go test jobs to publish per-test `<details>`
sections in the job summary.
- Removed upload of the raw `go-test.json` artifact.
- Added upload of `go-test-failures-*.ndjson` with compact failure
records for deeper inspection.
- Deleted the old bash and `jq` summary script.

## Why

- The previous raw artifact was about 35 MB compressed and 445 MB raw in
the linked run.
- Passing-test output made the artifact noisy and slow to inspect.
- The old summary truncated output to 600 characters.
- The new path keeps streaming, bounded output and writes structured
diagnostics for only final failed tests.

## Validation

- `gofmt -w scripts/gotestsummary`
- `gofmt -l scripts/gotestsummary`
- `go test ./scripts/gotestsummary/...`
- `go vet ./scripts/gotestsummary/...`
- `grep -rn 'go-test-failure-summary.sh' . || true`
- `grep -rn 'go-test-failure-summary.sh\|go-test.json\|go-test-json-'
.claude .agents docs AGENTS.md || true`
- `make lint/agents`
- `make lint/emdash`
- `make lint/markdown`
- `make lint/shellcheck`
- `git diff --check origin/main..HEAD`

> This PR was prepared by Mux working on Mike's behalf.
2026-05-12 00:08:37 +02:00
Garrett Delfosse aed43d9b61 fix: update coder/tailscale to 85c03fc8fb2a (#24824)
Updates `coder/tailscale` fork to
[`85c03fc8fb2a`](https://github.com/coder/tailscale/commit/85c03fc8fb2ad8fdf5b9328be5d277aaa83afdff),
which includes the DNS resilience fix from
https://github.com/coder/tailscale/pull/114 (preserve NRPT rules on
startup and improve hosts file retry).

---

> Generated by Coder Agents
2026-05-11 17:35:33 -04:00
Kyle Carberry 0ed57ee343 fix(coderd/x/chatd): checkpoint buffered message_parts to avoid stale replay (#25145) 2026-05-11 17:27:03 -04:00
Sushant P 81561454d6 revert: "fix(site): enlarge checkbox click target in workspace and task tables" (#25159)
Reverts coder/coder#24739
2026-05-11 13:59:04 -07:00
J. Scott Miller 3e46c7986f feat: event driven agent connection metric (#24355)
Moves the `coderd_agents_first_connection_seconds` histogram from the
polling-based `prometheusmetrics.Agents()` loop to the event-driven
`agentConnectionMonitor.init()` path. The metric is now recorded exactly
once when an agent first connects over the RPC websocket, instead of
being retroactively computed each polling tick.

The `username` and `workspace_name` labels are removed to reduce
cardinality; only `template_name` and `agent_name` are retained.

Adds unit tests covering both the happy path (first connection recorded)
and the negative-duration guard (clock skew logs a warning, no sample
emitted).
2026-05-11 14:27:40 -05:00
Thomas Kosiewski e56381eb61 feat: stream advisor tool output (#25032)
Stream advisor output into the advisor tool card while the nested
advisor call is still running.

This keeps the advisor implementation intentionally advisor-specific:
the parent model still receives the same final structured tool result,
while the frontend receives transient `tool-result.result_delta` parts
to render partial advisor text in the expanded card. The final persisted
chat history remains unchanged.

Refs CODAGT-322.

Generated by Coder Agents.

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

- Publish advisor text deltas from the nested `chatloop.Run` via
`RunAdvisorOptions.OnAdviceDelta`.
- Forward those deltas through `chatadvisor.Tool` with the parent
advisor tool call ID.
- Emit transient `ChatMessagePartTypeToolResult` websocket parts with
`ResultDelta` from `chatd`.
- Add `result_delta` to the generated tool-result TypeScript variant.
- Accumulate tool result deltas in frontend stream state and keep the
tool running until the final result arrives.
- Render streamed advisor advice in the existing advisor card using
streaming markdown mode, while retaining the updated advisor UI.

</details>
2026-05-11 20:18:49 +02:00
Michael SuchaczandCoder Agents 6bb88775ab test(coderd/x/chatd): pin TestGetWorkspaceConn_StatusCheck to mock clock (#25130)
The `TimedOutAgentCacheHit`, `CacheHitHealthyAgent`, and
`CacheHitDBError` subtests of `TestGetWorkspaceConn_StatusCheck` built
their `WorkspaceAgent` timestamps with `time.Now()` in the parent test's
slice literal and then ran the actual check against the server's real
wall clock (`quartz.NewReal()`). On slow Windows CI runners, more than
`agentInactiveDisconnectTimeout` (30s) of wall time can elapse between
slice construction and the parallel subtest body. In that window, the
cached "healthy" agent gets reclassified as disconnected by
`agentDisconnectedFor`, and `CacheHitHealthyAgent` fails with
`errChatAgentDisconnected` instead of returning the cached connection.

Build each agent inside the subtest with `quartz.NewMock(t)` and feed
the same clock into the `Server` so the agent timestamps and the status
math share a single frozen `now`. This matches the pattern already used
by `TestGetWorkspaceConn_DialTimeoutDisconnectedRecoveryThreshold` in
the same file.

Closes https://github.com/coder/internal/issues/1522

<details>
<summary>Verification</summary>

Inserting `time.Sleep(35 * time.Second)` at the top of each subtest's
body reliably reproduces the original failure
(`errChatAgentDisconnected` on `CacheHitHealthyAgent`) on the parent
commit and passes with this change. After removing the synthetic sleep,
`go test ./coderd/x/chatd -run TestGetWorkspaceConn_StatusCheck
-count=50` passes cleanly.

</details>

> Generated by Coder Agents on behalf of the assignee.

Co-authored-by: Coder Agents <noreply@coder.com>
2026-05-11 19:53:58 +02:00
Kyle Carberry e3db203011 fix(coderd/azureidentity): set explicit roots to avoid macOS system verifier (#25136)
Fixes
[CODAGT-372](https://linear.app/codercom/issue/CODAGT-372/coderdazureidentity-testvalidateregular-fails-on-macos).
Closes coder/internal#101.

## Problem

`coderd/azureidentity TestValidate/regular` fails on macOS with:

```
verify signature:
    github.com/coder/coder/v2/coderd/azureidentity.Validate
        /Users/runner/work/coder/coder/coderd/azureidentity/azureidentity.go:75
  - x509: “metadata.azure.com” certificate is not standards compliant
```

When `crypto/x509.VerifyOptions.Roots` is `nil`, Go's verifier on
macOS/iOS falls back to the system verifier (`systemVerify` in
`crypto/x509/root_darwin.go`), which delegates to Apple's
`SecTrustEvaluateWithError`. Apple's framework enforces stricter
standards-compliance checks than Go's pure-Go verifier and rejects some
otherwise valid Azure instance-identity leaf certificates with
`errSecCertificateIsNotStandardsCompliant`, surfaced as the `not
standards compliant` error.

The test had been skipped on darwin since #12979 (April 2024) as a
workaround.

## Fix

- Embed the three root CAs that Azure instance-identity certificates
ultimately chain to:
  - DigiCert Global Root G2
  - DigiCert Global Root G3
- Baltimore CyberTrust Root (kept for historical chains via `Microsoft
RSA TLS CA 01/02`)
- In `Validate`, populate `options.Roots` from those embedded roots when
the caller does not supply its own pool. Because `Roots != nil`, Go no
longer takes the `systemVerify` path on darwin and uses the pure-Go
verifier on all platforms.
- Remove the `runtime.GOOS == "darwin"` skip from `TestValidate`.
- Add `TestEmbeddedRoots` to guard against future regressions in the
embedded root list (parses each PEM, asserts self-signed, requires all
three named roots).

The caller's existing `Intermediates` handling is unchanged. Tests that
pass their own `Roots` (e.g. `coderdtest.NewAzureInstanceIdentity`) are
unaffected.

## Verification

On Linux:

```
$ go test ./coderd/azureidentity/ -race -count=1 -v
=== RUN   TestValidate
=== RUN   TestValidate/regular
=== RUN   TestValidate/govcloud
=== RUN   TestValidate/rsa
--- PASS: TestValidate (0.00s)
    --- PASS: TestValidate/regular (0.00s)
    --- PASS: TestValidate/rsa (0.00s)
    --- PASS: TestValidate/govcloud (0.00s)
=== RUN   TestEmbeddedRoots
--- PASS: TestEmbeddedRoots (0.00s)
=== RUN   TestExpiresSoon
--- SKIP: TestExpiresSoon (0.00s)
PASS
ok      github.com/coder/coder/v2/coderd/azureidentity 1.020s
```

The `test-go-pg` job on `macos-latest` in CI is the authoritative
confirmation of the fix on macOS; previously it would have failed
`TestValidate/regular` had the skip been removed.

<details>
<summary>Why this is the correct fix</summary>

From `/usr/local/go/src/crypto/x509/verify.go`:

```go
// Use platform verifiers, where available, if Roots is from SystemCertPool.
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
    systemPool := systemRootsPool()
    if opts.Roots == nil && (systemPool == nil || systemPool.systemPool) {
        return c.systemVerify(&opts)
    }
    ...
}
```

Setting `opts.Roots` to any non-nil, non-system pool deterministically
routes verification through Go's pure-Go verifier, bypassing Apple's
stricter compliance checks. The embedded roots are sufficient to
validate every chain we currently care about, since every intermediate
in `Certificates` ultimately issues to one of the three embedded roots.

</details>

> Generated by Coder Agents. Reviewed manually.
2026-05-11 13:53:33 -04:00
Michael Suchacz 60779ad2ec test(coderd/x/chatd): stop waking acquireLoop in TestResolveExploreToolSnapshot (#25129)
Fixes [CODAGT-367](https://linear.app/codercom/issue/CODAGT-367).

`TestResolveExploreToolSnapshot/*` flaked on CI (Linux and Windows) with
`context deadline exceeded` on the `GetMCPServerConfigsByIDs` call
inside `resolveExploreToolSnapshot`.

Each test setup called `server.CreateChat` twice with `MCPServerIDs` set
to fake `.example.com` URLs. `CreateChat` marks the chat pending and
calls `signalWake`, which causes the chatd background `acquireLoop` to
pick the chat up. That goroutine then dialed the fake MCP URLs
(NXDOMAIN, slower on Windows) and made an OpenAI request with the dbgen
default test key (401). Under CI load, that activity racing the 4
parallel subtests' `GetMCPServerConfigsByIDs` calls was enough to exceed
the 25s test context deadline. The failure logs in the issue showed both
side effects firing in the same job.

`resolveExploreToolSnapshot` only reads `ID`, `MCPServerIDs`,
`PlanMode`, `ParentChatID`, and `Mode` off the parent argument, so the
chats do not need to be persisted. Build them as in-memory
`database.Chat` values instead. The MCP server configs remain in the DB
because the function still queries them via `GetMCPServerConfigsByIDs`.

Verified locally with `go test ./coderd/x/chatd -run
TestResolveExploreToolSnapshot -count=100 -race` (passes, ~5s total) and
the surrounding `TestResolve*` / `TestCreateChildSubagentChat*` /
`TestSpawnAgent_Explore*` tests.

---

_Made by Coder Agents on behalf of @ibetitsmike. [Linear
session](https://linear.app/codercom/issue/CODAGT-367/flake-testresolveexploretoolsnapshot#agent-session-0730f3fe)._
2026-05-11 19:46:59 +02:00
Steven Masley 19573e8aee feat!: patchTemplateMeta to use optional fields (#24984)
Closes https://github.com/coder/coder/issues/13112

**Breaking Change**: Removed status code `StatusNotModified` when no
diffs occur in a patch. Now the patch is always applied and a template
is always returned.
2026-05-11 12:43:52 -05:00
Mathias Fredriksson 3986aa8a51 feat(agent/agentfiles): add post-fail diagnostic hints for edit_files (#25092)
When fuzzyReplace exhausts its passes, append a hint to the generic
"search string not found" error.

Inversion: if search did not match but replace does, list the lines
where replace appears.

Miscount: when a search line agrees with a file line except for the
count of one repeated rune, name the codepoint and counts.

Miscount takes precedence; both firing could direct an agent to swap
fields and corrupt the inversion anchor.

  Did you swap "search" and "replace"? Your replace string appears
  at line 12, 47, 89.

  Your search has 32 "─" (U+2500); the file has 37 at line 182.

Closes CODAGT-330
2026-05-11 17:28:12 +00:00
Michael Suchacz 6cf95366ed docs(.agents/skills/pull-requests): warn against hard-wrapping PR bodies (#25141)
PR bodies copied from a commit message body keep their 72/80-column hard
wraps, and GitHub renders those as ragged-right line breaks instead of
soft-wrapped paragraphs (e.g. the original body of #25130, fixed in this
branch).

The rule already exists in `.claude/docs/PR_STYLE_GUIDE.md`, but it is
buried in a 200-line style guide and easy to miss when an agent is
mechanically running `gh pr create`. This change adds a short "Body
Formatting" section directly to `.agents/skills/pull-requests/SKILL.md`,
which is the proximate context loaded at PR-write time, and explicitly
tells callers to unwrap commit-message paragraphs before reusing them as
a PR body.

> Generated by Coder Agents on behalf of the assignee.
2026-05-11 19:18:28 +02:00
Michael SuchaczandCoder Agents 645b8cc63d fix(coderd/x/chatd/chaterror): deflake TestClassify_ParsesRetryAfterHTTPDate (#25128)
The test built a `Retry-After` HTTP-date with
`time.Now().Add(3*time.Second).UTC().Format(http.TimeFormat)`, then
asserted that the parsed `RetryAfter` was `>= 2s`. `http.TimeFormat` has
second precision, so `Format()` truncates up to ~1s. Combined with the
small elapsed time between formatting in the test and `time.Until()` in
production, the value could land just under `offset-1s` (1.997s observed
in CI), failing the lower bound.

Round the formatted target up to the next whole second so the parsed
deadline is never earlier than `now+offset`, and assert against a
symmetric `[offset-1s, offset+1s]` window.

Closes
[CODAGT-365](https://linear.app/codercom/issue/CODAGT-365/flake-testclassify-parsesretryafterhttpdate)
Refs https://github.com/coder/internal/issues/1512

<sub>Created by [Coder Agents](https://coder.com/docs/agent).</sub>

Co-authored-by: Coder Agents <coderagents@coder.com>
2026-05-11 19:09:51 +02:00
dependabot[bot] 56941a1600 chore: bump next from 15.5.16 to 15.5.18 in /offlinedocs (#25138)
Bumps [next](https://github.com/vercel/next.js) from 15.5.16 to 15.5.18.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v15.5.18</h2>
<p>This release contains security fixes for the following
advisories:</p>
<p>High:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-8h8q-6873-q5fj">GHSA-8h8q-6873-q5fj:
Denial of Service with Server Components</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-267c-6grr-h53f">GHSA-267c-6grr-h53f:
Middleware / Proxy bypass in App Router applications via
segment-prefetch routes</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-26hh-7cqf-hhc6">GHSA-26hh-7cqf-hhc6:
Middleware / Proxy bypass in App Router applications via
segment-prefetch routes - Incomplete Fix Follow-Up</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-mg66-mrh9-m8jx">GHSA-mg66-mrh9-m8jx:
Denial of Service via connection exhaustion in applications using Cache
Components</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-492v-c6pp-mqqv">GHSA-492v-c6pp-mqqv:
Middleware / Proxy bypass through dynamic route parameter
injection</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-c4j6-fc7j-m34r">GHSA-c4j6-fc7j-m34r:
Server-side request forgery in applications using WebSocket
upgrades</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-36qx-fr4f-26g5">GHSA-36qx-fr4f-26g5:
Middleware / Proxy bypass in Pages Router applications using
i18n</a></li>
</ul>
<p>Moderate:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-ffhc-5mcf-pf4q">GHSA-ffhc-5mcf-pf4q:
Cross-site scripting in App Router applications using CSP
nonces</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-gx5p-jg67-6x7h">GHSA-gx5p-jg67-6x7h:
Cross-site scripting in beforeInteractive scripts with untrusted
input</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-h64f-5h5j-jqjh">GHSA-h64f-5h5j-jqjh:
Denial of Service in the Image Optimization API</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-wfc6-r584-vfw7">GHSA-wfc6-r584-vfw7:
Cache poisoning in React Server Component responses</a></li>
</ul>
<p>Low:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-vfv6-92ff-j949">GHSA-vfv6-92ff-j949:
Cache poisoning via collisions in React Server Component
cache-busting</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-3g8h-86w9-wvmq">GHSA-3g8h-86w9-wvmq:
Middleware / Proxy redirects can be cache-poisoned</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/9ff92cebcaa6ba4e7463b6fd037a8510ba9b81ec"><code>9ff92ce</code></a>
v15.5.18</li>
<li><a
href="https://github.com/vercel/next.js/commit/00ebe23562bd7eb32dd78730984bfadb47138bcf"><code>00ebe23</code></a>
[backport] Disable build caches for production/staging/force-preview
deploys ...</li>
<li><a
href="https://github.com/vercel/next.js/commit/62c97ab0b5825e2cbc15f6b682d8286a8dd6a038"><code>62c97ab</code></a>
v15.5.17</li>
<li><a
href="https://github.com/vercel/next.js/commit/423623ae38c106273085b66946ee5bf9aab77f2c"><code>423623a</code></a>
Turbopack: Match proxy matchers with webpack implementation (<a
href="https://redirect.github.com/vercel/next.js/issues/93594">#93594</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/fa787399b38d9aa702118f9bd23a8315b9f0ecc6"><code>fa78739</code></a>
Turbopack: Fix middleware matcher suffix (<a
href="https://redirect.github.com/vercel/next.js/issues/93590">#93590</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/36e62c6eb7813e42d409eb487f93b829f4ad77e8"><code>36e62c6</code></a>
[backport] Turbopack: more strict vergen setup (<a
href="https://redirect.github.com/vercel/next.js/issues/93588">#93588</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/36589b5db512b7704cdadd873cbe49b6dbcc9261"><code>36589b5</code></a>
[backport][test] Pin package manager to patch versions (<a
href="https://redirect.github.com/vercel/next.js/issues/93596">#93596</a>)</li>
<li>See full diff in <a
href="https://github.com/vercel/next.js/compare/v15.5.16...v15.5.18">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=next&package-manager=npm_and_yarn&previous-version=15.5.16&new-version=15.5.18)](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-05-11 17:03:21 +00:00
Cian Johnston e8508b2d90 fix: recover chatd from poisoned chain anchor on retry (#25097)
When OpenAI's Responses API returns `Previous response with id ... not
found` for a chained turn, classify it as a `ChainBroken` retry, clear
`previous_response_id`, exit chain mode, reload full history, and let
`chatretry` retry. Self-heals chats whose anchor was poisoned before
#25074 stopped truncated streams from being persisted as a successful
turn with a stored response id.

The new state is exposed via the existing
`coderd_chatd_stream_retries_total` counter as a
`chain_broken="true"|"false"` label. Aggregating queries (`sum`, `rate`
over `provider`/`model`/`kind`) keep working without changes; raw-series
matchers without aggregation will now see two series per `(provider,
model, kind)` where they previously saw one. The metric is internal-only
so the blast radius should be small, but if you have dashboards that
index by exact label matchers without aggregation they will need an
extra `sum` or an explicit `chain_broken` selector.

> 🤖 This PR was created with the help of Coder Agents, and was reviewed by a human 🧑‍💻
2026-05-11 17:43:40 +01:00
TJ c2dfaa406a fix(site): enlarge checkbox click target in workspace and task tables (#24739)
Fixes a UX issue where clicking near (but not exactly on) the
bulk-action
checkbox in the Workspaces or Tasks table would navigate to the
workspace/task page instead of toggling the checkbox. Clicking back then
clears all previous selections.

## Changes

Wraps each row checkbox in a `div` that:
- Calls `e.stopPropagation()` on `click` and `keydown` so near-miss
  clicks toggle the checkbox instead of navigating.
- Uses `h-[72px]` to fill the full row height for vertical coverage.
- Uses `pr-4 -mr-4` to extend the safe zone to the right without
  shifting layout.
- Sets `cursor-default` so the pointer hand does not appear in the
  safe zone.

Applied to both:
- `WorkspacesTable.tsx` (workspaces page)
- `TasksTable.tsx` (tasks page)

> This PR was authored by Coder Agents.
2026-05-11 16:37:00 +00:00
dependabot[bot] 0a17660691 chore: bump next from 15.5.15 to 15.5.16 in /offlinedocs (#25131)
Bumps [next](https://github.com/vercel/next.js) from 15.5.15 to 15.5.16.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v15.5.16</h2>
<p>This release contains security fixes for the following
advisories:</p>
<p>High:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-8h8q-6873-q5fj">GHSA-8h8q-6873-q5fj:
Denial of Service with Server Components</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-267c-6grr-h53f">GHSA-267c-6grr-h53f:
Middleware / Proxy bypass in App Router applications via
segment-prefetch routes</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-mg66-mrh9-m8jx">GHSA-mg66-mrh9-m8jx:
Denial of Service via connection exhaustion in applications using Cache
Components</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-492v-c6pp-mqqv">GHSA-492v-c6pp-mqqv:
Middleware / Proxy bypass through dynamic route parameter
injection</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-c4j6-fc7j-m34r">GHSA-c4j6-fc7j-m34r:
Server-side request forgery in applications using WebSocket
upgrades</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-36qx-fr4f-26g5">GHSA-36qx-fr4f-26g5:
Middleware / Proxy bypass in Pages Router applications using
i18n</a></li>
</ul>
<p>Moderate:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-ffhc-5mcf-pf4q">GHSA-ffhc-5mcf-pf4q:
Cross-site scripting in App Router applications using CSP
nonces</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-gx5p-jg67-6x7h">GHSA-gx5p-jg67-6x7h:
Cross-site scripting in beforeInteractive scripts with untrusted
input</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-h64f-5h5j-jqjh">GHSA-h64f-5h5j-jqjh:
Denial of Service in the Image Optimization API</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-wfc6-r584-vfw7">GHSA-wfc6-r584-vfw7:
Cache poisoning in React Server Component responses</a></li>
</ul>
<p>Low:</p>
<ul>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-vfv6-92ff-j949">GHSA-vfv6-92ff-j949:
Cache poisoning via collisions in React Server Component
cache-busting</a></li>
<li><a
href="https://github.com/vercel/next.js/security/advisories/GHSA-3g8h-86w9-wvmq">GHSA-3g8h-86w9-wvmq:
Middleware / Proxy redirects can be cache-poisoned</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/ad6fd4e50e5aba20b60d283c42b89273a3167ccd"><code>ad6fd4e</code></a>
v15.5.16</li>
<li><a
href="https://github.com/vercel/next.js/commit/79d7dff1448483f0c8f187f98887b31019f6e494"><code>79d7dff</code></a>
Ignore malformed CSP nonce headers (<a
href="https://redirect.github.com/vercel/next.js/issues/103">#103</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8"><code>c4f6908</code></a>
router-server: guard upgrade proxy against absolute-url SSRF (<a
href="https://redirect.github.com/vercel/next.js/issues/77">#77</a>) (<a
href="https://redirect.github.com/vercel/next.js/issues/102">#102</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/6c72e0b4ee096643b42c742f35e0de84c41d190d"><code>6c72e0b</code></a>
Fix i18n middleware matching for default-locale data routes (<a
href="https://redirect.github.com/vercel/next.js/issues/82">#82</a>) (<a
href="https://redirect.github.com/vercel/next.js/issues/100">#100</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/3e247110b33f3bee3d05cfbac342581051cdf405"><code>3e24711</code></a>
fix: add explicit checks for RSC header (<a
href="https://redirect.github.com/vercel/next.js/issues/83">#83</a>) (<a
href="https://redirect.github.com/vercel/next.js/issues/99">#99</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/25926510f8d3223a447f2e37a56a7686f9190ef2"><code>2592651</code></a>
fix proxy matching for segment prefetch URLs (<a
href="https://redirect.github.com/vercel/next.js/issues/89">#89</a>) (<a
href="https://redirect.github.com/vercel/next.js/issues/97">#97</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/73de04589560027c14d6ab579392297828ceec71"><code>73de045</code></a>
Strip next-resume header from incoming requests (<a
href="https://redirect.github.com/vercel/next.js/issues/93">#93</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/086dfa7f8fd284646266d8c757c9ab59b2ce1a43"><code>086dfa7</code></a>
Escape properties for beforeInteractive scripts (15.5) (<a
href="https://redirect.github.com/vercel/next.js/issues/87">#87</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/87080764c96f5416decccd43f4c434545fd5d4e1"><code>8708076</code></a>
fix: skip internal param normalization in unsupported environments</li>
<li><a
href="https://github.com/vercel/next.js/commit/ebc1a54e7c0692486b69ea0760afea8508d110a6"><code>ebc1a54</code></a>
[15.x] Type hardening and performance improvements (<a
href="https://redirect.github.com/vercel/next.js/issues/81">#81</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vercel/next.js/compare/v15.5.15...v15.5.16">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 next since your current version.</p>
</details>
<br />


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

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

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

---

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

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 16:08:33 +00:00
dependabot[bot] c1c3b9784e chore: bump github.com/go-git/go-git/v5 from 5.18.0 to 5.19.0 (#25124)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git)
from 5.18.0 to 5.19.0.
<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.0</h2>
<h2>What's Changed</h2>
<ul>
<li>build: Update module github.com/go-git/go-git/v5 to v5.18.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/2010">go-git/go-git#2010</a></li>
<li>v5: Bump sha1cd and go-billy by <a
href="https://github.com/pjbgf"><code>@​pjbgf</code></a> in <a
href="https://redirect.github.com/go-git/go-git/pull/2060">go-git/go-git#2060</a></li>
<li>v5: Align object encoding with upstream by <a
href="https://github.com/pjbgf"><code>@​pjbgf</code></a> in <a
href="https://redirect.github.com/go-git/go-git/pull/2065">go-git/go-git#2065</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0">https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/go-git/go-git/commit/bc930f4cbe095a3e1d49273655f73fcef7d41a42"><code>bc930f4</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2065">#2065</a>
from go-git/commit-v5</li>
<li><a
href="https://github.com/go-git/go-git/commit/d315264343cead712aa9eb56475c2ec96f5ecef1"><code>d315264</code></a>
plumbing: object, Reset object before decode</li>
<li><a
href="https://github.com/go-git/go-git/commit/6e1d34890a4dae8a0df738e531234bd60b7e9b66"><code>6e1d348</code></a>
plumbing: object, Align Tree handling with upstream</li>
<li><a
href="https://github.com/go-git/go-git/commit/e134ba34cf95ed0167e5b1df36a933d7bde9d02d"><code>e134ba3</code></a>
tests: Skip double checks in Git v2.11</li>
<li><a
href="https://github.com/go-git/go-git/commit/1971422f6b1bec9176061b3293306981cfff981e"><code>1971422</code></a>
tests: Add git conformance tests for signing verification</li>
<li><a
href="https://github.com/go-git/go-git/commit/a387aa8857a8fbba8e74b7f5485e9e030669ab5d"><code>a387aa8</code></a>
plumbing: object, Add ErrMalformedTag</li>
<li><a
href="https://github.com/go-git/go-git/commit/f415670d906b5c6169d1fdc64f3f9f1d33eb6f9c"><code>f415670</code></a>
plumbing: object, Decode Tag headers via a state machine</li>
<li><a
href="https://github.com/go-git/go-git/commit/5b0cd38a62e2336bb5f1a2ad0eb8ac8f9e7b740e"><code>5b0cd38</code></a>
plumbing: object, Reject multi-signature commits at Verify</li>
<li><a
href="https://github.com/go-git/go-git/commit/fe8ed6223a6079d9fd84d853362a996e7df175fb"><code>fe8ed62</code></a>
plumbing: object, Align Tag.EncodeWithoutSignature with Commit</li>
<li><a
href="https://github.com/go-git/go-git/commit/98e337d5bdc4c0536a40ab7381b2231f7e0b15cd"><code>98e337d</code></a>
plumbing: object, Add support for Tag.SignatureSHA256</li>
<li>Additional commits viewable in <a
href="https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0">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.18.0&new-version=5.19.0)](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-05-11 15:57:33 +00:00
Michael Suchacz 85792d08bc feat: add harness engineering layer for agent workflows (#24791)
This PR adds an opinionated harness-engineering layer for agent-driven
workflows: a small set of agent-readable docs, mechanical structure
checks, structured CI failure summaries, an architecture-lint umbrella,
and per-worktree dev-server isolation. The goal is to make local dev,
tests, and CI mechanically inspectable by agents without changing app
runtime behavior.

## What landed

**Agent docs and navigation**
- `.claude/docs/OBSERVABILITY.md`, `.claude/docs/DEV_ISOLATION.md`,
`.claude/docs/AGENT_FAILURES.md`: task-oriented guides for logs,
tracing, Prometheus, dev-server isolation, and a seeded failure catalog.
- `AGENTS.md`: added an `Agent navigation` block, then trimmed the file
from 375 to 229 lines by migrating duplicated detail into
`WORKFLOWS.md`, `GO.md`, `TESTING.md`, and `DATABASE.md`. The
user-managed custom-instructions block is preserved.
- `.agents/docs`: symlink mirror of `.claude/docs` for agent runtimes
that look under `.agents`.

**Mechanical checks**
- `scripts/check_agents_structure.sh`: validates `@...` references in
tracked `AGENTS.md` files and warns when root grows past 600 lines.
Wired as `make lint/agents` and into `make lint`.
- `scripts/audit-agent-readiness.sh`: report-first audit of harness
readiness. Currently `10 ok, 0 warn, 0 fail`.
- `scripts/check_architecture.sh` / `make lint/architecture`: umbrella
architecture-lint target. Consolidates the existing
`check_enterprise_imports.sh` and `check_codersdk_imports.sh` so they
run exactly once via the umbrella. Slot is open for new high-confidence
rules.

**Structured CI failure summaries**
- `scripts/playwright-failure-summary.sh`: parses
`site/test-results/results.json` and writes Markdown to
`$GITHUB_STEP_SUMMARY` on failure. Wired into the `test-e2e` matrix job.
- `scripts/go-test-failure-summary.sh`: parses `go test -json`
line-delimited output the same way. Wired into `test-go-pg`,
`test-go-pg-17`, and `test-go-race-pg` by injecting `gotestsum
--jsonfile` in the workflow without touching `Makefile`. JSON also
uploaded as a CI artifact on failure.
- `site/e2e/playwright.config.ts`: enables `screenshot:
only-on-failure`, `trace: retain-on-failure`, JSON reporter, and HTML
reporter alongside existing reporters.
- `.github/workflows/ci.yaml`: failure artifact uploads for Playwright
now use `if: failure()` and predictable names
(`playwright-artifacts-<variant>-<sha>`).

**Per-worktree dev-server isolation** (`scripts/develop/main.go`)
- Deterministic FNV-64a hash of the worktree path produces a port offset
in `[0, 1000)` (50 buckets, step 20 to avoid API/proxy overlap across
adjacent buckets).
- Offset is applied only to defaults; both env vars (`CODER_DEV_PORT`,
`CODER_DEV_WEB_PORT`, `CODER_DEV_PROXY_PORT`,
`CODER_DEV_PROMETHEUS_PORT`) and CLI flags retain priority.
- Hardcoded ports `9090` (embedded Prometheus UI) and `12345` (Delve)
are unchanged by design.
- Startup banner shows each port's source: `default`, `offset`, or
`explicit`.
- Unit tests in `scripts/develop/main_test.go` cover determinism,
bounds, no-overlap across the four ports, and explicit-skip behavior.
- State (`.coderv2/`) was already worktree-isolated via `os.Getwd()`, so
no state-dir changes were needed.

## Validation

`make lint/agents`, `make lint/architecture`, `make lint/emdash`, `bash
scripts/audit-agent-readiness.sh` (10 ok, 0 warn, 0 fail), `shellcheck`
on all 5 new scripts, `go test ./scripts/develop/...`, and `js-yaml`
parse of `ci.yaml` all pass. Synthetic fixtures verify both
failure-summary scripts handle empty/missing input (silent exit 0),
ANSI-stripped output, and parent/subtest formatting.

## Known follow-ups (deferred)

- Frontend Storybook/Vitest failure summary: lowest-leverage slice of
the failure-summary work. Skipping until observed pain.
- Architecture lint currently only delegates to existing import checks;
new rules (`InTx` outer-store detection, swagger-annotation lint) plug
in as needed.
- 50 port-offset buckets means two worktree paths can occasionally
collide. The DEV_ISOLATION doc tells users to set the relevant env var
when this happens.

> Mux opened this PR on Mike's behalf.
2026-05-11 17:27:29 +02:00
Michael Suchacz 915956460a feat(coderd/x/chatd): add compact turn status labels (#25043)
> Mux is acting on Mike's behalf.

Changes chat turn-end summaries into compact status labels for the
cached `last_turn_summary` and successful web push body.

Uses a structured-output model call for successful turns, requiring a
2-5 word `label` and validating it to reject agent-centric phrasing.
Pending and requires-action states keep deterministic status labels.

Removes the earlier deterministic tool-signal pipeline in favor of the
smaller structured-output path.
2026-05-11 17:09:42 +02:00
Zach b221632615 fix: wipe user secrets when user is soft-deleted (#24985)
Extend the delete_deleted_user_resources() trigger so that secrets
belonging to a soft-deleted user are removed in the same transaction as
the existing api_keys and user_links cleanup.

user_secrets.user_id has ON DELETE CASCADE, but Coder soft-deletes users
by flipping users.deleted rather than removing the row, so the foreign key
cascade never fires and secrets would otherwise survive deletion.

Assisted by Coder Agents.
2026-05-11 09:07:30 -06:00
Zach 81e2be69e9 test: use typed atomics in test files (#25071)
Use typed atomics (atomic.Int64, atomic.Int32, etc.) in test files to prevent
mixing atomic and non-atomic access on the same value, guarantee 64-bit
alignment on 32-bit platforms, and provide a cleaner API.
2026-05-11 08:41:17 -06:00
Jeremy Ruppel a1dbd758bc feat: add template builder deployment config and telemetry types (#25082) 2026-05-11 09:48:55 -04:00
Michael SuchaczandCursor 67aa625579 chore: add coder-agents-review skill (#25121)
## Summary

- Adds the `coder-agents-review` agent skill that drives PRs through the
`coder-agents-review` GitHub app review loop
- The skill automates: triggering review, waiting for feedback, fixing
issues, validating, and re-requesting until approved

## Test plan

- [ ] Verify the skill file is well-formed and the loop instructions are
correct
- [ ] Test triggering the skill on a PR with `/coder-agents-review`


Made with [Cursor](https://cursor.com)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 13:14:28 +00:00
Michael Suchacz abe9f44e03 chore: add coder agents review (#25088)
Added a coder-agents-review skill covering:

- when to request review
- how to paginate app activity before deriving state
- how to require exact app identity and explicit approval evidence

> Mux is acting on Mike's behalf.
2026-05-11 15:58:30 +03:00
Mathias Fredriksson ca6450cf94 fix(agent): gate MCP tool discovery on startup (#25034)
The first `/mcp/tools` request could race workspace startup and return
an empty tool list before startup scripts had a chance to write
`.mcp.json`. Chatd may only discover tools once for a turn, so that
empty response could hide workspace MCP tools even though the agent
loaded them later.

Make the manager wait for startup to settle before treating missing MCP
config files as a real empty state. Tool listing now goes through one
manager-owned path that starts reload work independently of caller
cancellation; caller contexts only bound that caller's wait. After the
first reload body settles, transient reload errors return cached tools
with the error so the HTTP handler can degrade to the last known tool
set instead of returning `[]`.

The handler is intentionally thin: it asks the manager for tools, logs
any degraded path, and still returns the tool response shape callers
already expect. Tests cover startup gating, caller-canceled waits,
manager close, reload timeout via quartz, and cached-tool fallback after
a later reload error.
2026-05-11 12:57:22 +03:00
Thomas Kosiewski 4a6756a3e8 fix: isolate test HTTP clients (#25038) 2026-05-11 11:03:38 +02:00
Marcin Tojek febabfb8b2 feat: add request/response dump support to aibridgeproxyd (#24837)
Closes https://github.com/coder/coder/issues/24335
2026-05-11 10:59:26 +02:00
Mathias Fredriksson fb60bb0c08 chore(coderd/x/chatd): instrument PromoteQueued + stream subscriber for ENG-2645 (#25085)
TestPromoteQueuedWhileRequiresActionMixedTools has flaked three times across
Windows and Ubuntu CI runners since 2026-05-06; local repro on the dev
workspace has not surfaced it. The May 8 Ubuntu log shows all four
PromoteQueued post-TX pubsub publishes reaching pg_notify, yet the test still
times out 25s later, so the failure is downstream between the subscriber's
listener and the test's events channel. Adds three Debug-level markers in
chatd.go (no logic change) plus two t.Logf markers in the test's reader so
the next CI occurrence pins down exactly which step failed.

Closes ENG-2645
Closes coder/internal#1523
2026-05-11 08:33:46 +00:00
Ethan 063c06ca5f test: prevent expired contexts in chatd parallel subtests (#25107)
Parallel subtests in `coderd/x/chatd` reused a parent test context with
a `testutil.WaitLong` deadline, so the context could expire before a
subtest was scheduled under load. That made the subagent lifecycle tools
return plain-text context errors instead of the expected JSON payload,
causing flaky JSON unmarshal failures.

Create fresh `chatdTestContext` values inside the affected parallel
subtests and add `chatdTestContext` to the `paralleltestctx` custom
function list so this pattern is caught by `make lint`.

Closes https://github.com/coder/internal/issues/1494
2026-05-11 17:48:27 +10:00
Ethan bd6cc1aaf2 feat(coderd): add stop_workspace chatd tool and recovery classification (#24997)
## Summary

Adds a `stop_workspace` tool to chatd so the model can recover from the
"workspace running but agent dead" failure mode (e.g. an OOM that leaves
the workspace running but the agent unreachable) by stopping and then
starting the workspace.

<img width="924" height="742" alt="image"
src="https://github.com/user-attachments/assets/279dedb6-6e29-4fe1-8754-3a1f01e538bf"
/>



## What changed

**New `stop_workspace` chatd tool**
(`coderd/x/chatd/chattool/stopworkspace.go`). Mirrors `start_workspace`:
shares `WorkspaceMu` to serialize with create/start, waits for any
in-progress build before issuing a stop, and is idempotent only after a
successful Stop transition. Failed stop builds re-attempt rather than
reporting success.

**New `chatStopWorkspace` coderd hook** (`coderd/exp_chats.go`). Mirrors
`chatStartWorkspace` minus the `RequireActiveVersion` gate. Stop should
not be blocked by template version policy.

**Differentiated recovery sentinels** (`coderd/x/chatd/chatd.go`).
`errChatAgentDisconnected` instructs the model to call `stop_workspace`
then `start_workspace`. `errChatDialTimeout` instructs a single retry,
then user escalation if it repeats. The previous single message
conflated transient and persistent failures.

**Two-signal recovery gate.** Recovery is only surfaced when a tool call
times out *and* a fresh DB read of the latest workspace agent says
`Disconnected`. The previous draft escalated on the DB read alone, which
would fire on a 30-second heartbeat blip (e.g. agent respawn) and prompt
a destructive stop/start unnecessarily.

**Cache-hit disconnected handling** now clears the cache and retries a
fresh dial before escalating, rather than returning the recovery
sentinel immediately. Latest-agent classification uses
`GetWorkspaceAgentsInLatestBuildByWorkspaceID` instead of the chat's
bound `AgentID`, so stale bindings after a rebuild don't misclassify.

**Shared chattool helpers** in `coderd/x/chatd/chattool/chattool.go`:
`latestWorkspaceBuildAndJob`, `publishBuildBinding`,
`provisionerJobTerminal`. Applied to both `start_workspace` and
`stop_workspace`.

## Notes

- Reverts an earlier draft that widened `ask_user_question` to root
standard turns. Plan-mode-only behavior is restored.
- The `stop_workspace` tool currently renders via the generic chat
tool-call UI. A follow-up frontend PR will prettify the `stop_workspace`
tool and style it like the `start_workspace` tool.
- Never-connected (`Timeout` status) agents are intentionally excluded
from recovery. They indicate template or startup failure, not the
running-but-dead case this PR targets.

Closes CODAGT-315
2026-05-11 16:23:07 +10:00