mirror of
https://github.com/coder/coder.git
synced 2026-09-21 12:44:32 +08:00
cee504e8a0f253a1111712a7d6e8d3d172f1085a
14198
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cee504e8a0 |
docs: remove reference to defunct template creation wizard permission feature (#25104)
#11918 took away advanced settings during template creation however it did not clean up the documentation of a reference to customising the template permissions during template creation - https://coder.com/docs/admin/templates/template-permissions > By default the Everyone group is assigned to each template meaning any Coder user can use the template to create a workspace. To prevent this, disable the Allow everyone to use the template setting when creating a template. This setting is no longer present in Coder, so removing it from the docs. |
||
|
|
aaa0dacdb3 |
fix: infer workspace claim time from build history for /agents delete dialog (#25057)
Closes [CODAGT-317](https://linear.app/codercom/issue/CODAGT-317/pr-workspaces-sometimes-require-name-confirmation-to-delete). ## Problem The `/agents` archive-and-delete molly-guard (typing the workspace name) was firing for chats that had clearly created their own workspace. The heuristic in `resolveArchiveAndDeleteAction` decides whether confirmation is needed by comparing the workspace's `created_at` against the chat's `created_at`: ```ts return new Date(workspaceCreatedAt) >= new Date(chatCreatedAt); ``` That assumption breaks for **prebuilt workspaces**. `ClaimPrebuiltWorkspace` rewrites `owner_id`, `name`, `updated_at`, `last_used_at`, etc., but **never touches `created_at`**, which still reflects when the prebuild was provisioned by the reconciler, often hours before the chat exists. Result: every prebuild-claimed workspace looks pre-existing, so the molly-guard fires. Concrete example from a real chat: | Field | Value | |---|---| | `chat.created_at` | `2026-05-07T15:12:23Z` | | `workspace.created_at` (provision) | `2026-05-07T14:22:24Z` | | `latest_build.created_at` (claim) | `2026-05-07T15:19:09Z` | `14:22:24 < 15:12:23` so `isWorkspaceAutoCreated` returned false even though the chat issued the claim. ## Fix (frontend-only) Derive the moment a workspace was acquired from existing build history rather than relying on `workspace.created_at`: - Build #1 initiator = prebuilds system user → workspace was a prebuild → use `build_2.created_at` (the claim build) as the acquisition time. - Build #1 initiator = real user → workspace was created from scratch → use `workspace.created_at` (unchanged behavior). - Unclaimed prebuild or no build history → return `null` (force confirmation; safe degradation for a destructive flow). The resolver fetches the build list via the existing `getWorkspaceBuilds` endpoint when the dialog might fire. No new column, no migration, no schema change. Works retroactively for all existing claimed prebuilds; no backfill needed. The prebuilds system user UUID is exposed via `codersdk.PrebuildsSystemUserID` and typegen'd to `typesGenerated.ts`. `coderd/database.PrebuildsSystemUserID` parses that constant via `uuid.MustParse` so the two cannot drift; if the codersdk literal ever changes, package init fails fast. ## History The first draft of this PR added a `workspaces.claimed_at` column populated by `ClaimPrebuiltWorkspace`. After review feedback from @johnstcn pointing out that the same fact is already implicit in build history, I pivoted to the frontend-only approach. Subsequent review notes consolidated the prebuilds system user UUID into a single typegen'd constant. ## Why not the other open PRs - **#25055** (`chatKey` cache fallback) only fixes a different cache-miss path; it explicitly notes it does not address `created_at < chat.created_at`. - **#25053** (`chats.workspace_auto_created` boolean) puts the truth on the wrong side of the schema: "this workspace was claimed at time T" is a property of the workspace, not the chat. The MCP plumbing it adds is also unnecessary now that the same answer is available from build history. ## Test plan - `pnpm vitest run --project=unit src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts` — 40/40 pass; new cases cover prebuild claim before/after chat, unclaimed prebuild, missing-build-history fallback, and the fetch-skip when the chat is not in cache. - `pnpm lint:types`, `pnpm check`, `make pre-commit`. <details> <summary>Disclosure</summary> Opened on behalf of @kylecarbs by [Coder Agents](https://coder.com/coder-agents). </details> |
||
|
|
4124d1137d |
feat: add ai_model_prices table (#24932)
# Summary Implements https://linear.app/codercom/issue/AIGOV-282/add-ai-model-price-table-and-seed-generator This PR lays the groundwork for AI Bridge cost controls (per the AI Governance RFC). It adds the foundation needed for future cost tracking: a place to store per-model token prices, a way to keep those prices in sync with upstream pricing data, and a startup mechanism that ensures every deployment has prices loaded before AI Bridge starts processing requests. The price data comes from [models.dev](https://models.dev/), a community-maintained catalogue of AI provider pricing. A generator script fetches the latest prices, filters to Anthropic and OpenAI for now, and produces a seed file checked into the repository. On every server startup the seed is applied to the database, so new releases automatically pick up any price corrections that landed since the previous one. Existing rows are overwritten with the latest prices; rows for models no longer in the seed are left untouched. # Batching the AI model price seed: three approaches Context: at server startup we seed the `ai_model_prices` table from an embedded JSON price book (~70 rows today, will grow as we add providers, potentially 4000+). Each row is: ```text (provider, model, input_price, output_price, cache_read_price, cache_write_price) ``` Any of the four price columns can be: - `NULL` → “price unknown for this dimension” - explicit `0` → “free” The batch must be an UPSERT so re-running is idempotent and existing rows pick up new prices. We considered three implementations. --- ## Approach 1 — Per-row UPSERT in a Go loop ```go for _, row := range rows { if err := db.UpsertAIModelPrice(ctx, database.UpsertAIModelPriceParams{ Provider: row.Provider, Model: row.Model, InputPrice: nullInt64(row.InputPrice), // ... }); err != nil { return err } } ``` ### Pros - Trivial. - NULL handling falls out naturally from `sql.NullInt64`. ### Cons - `N` round-trips per seed. - With ~70 rows that means ~70 statement executions on every startup, even inside a transaction. - Doesn't scale gracefully as the price book grows, potentially 4000+. --- ## Approach 2 — `UNNEST` with parallel arrays Pass each column as a separate Go slice. Postgres unnests them in parallel into a virtual table, then `INSERT ... SELECT`. ```sql INSERT INTO ai_model_prices ( provider, model, input_price, output_price, cache_read_price, cache_write_price ) SELECT UNNEST(@providers::text[]), UNNEST(@models::text[]), NULLIF(UNNEST(@input_prices::bigint[]), -1), NULLIF(UNNEST(@output_prices::bigint[]), -1), NULLIF(UNNEST(@cache_read_prices::bigint[]), -1), NULLIF(UNNEST(@cache_write_prices::bigint[]), -1) ON CONFLICT (provider, model) DO UPDATE SET input_price = EXCLUDED.input_price, output_price = EXCLUDED.output_price, cache_read_price = EXCLUDED.cache_read_price, cache_write_price = EXCLUDED.cache_write_price, updated_at = NOW(); ``` Go side: flatten rows into six parallel slices. Use a sentinel (`-1`) for “missing”, since `lib/pq` can't encode `NULL` into a `bigint[]` element. ```go providers := make([]string, len(rows)) models := make([]string, len(rows)) inputs := make([]int64, len(rows)) outputs := make([]int64, len(rows)) cacheR := make([]int64, len(rows)) cacheW := make([]int64, len(rows)) for i, r := range rows { providers[i] = r.Provider models[i] = r.Model inputs[i] = -1 if r.InputPrice != nil { inputs[i] = *r.InputPrice } outputs[i] = -1 if r.OutputPrice != nil { outputs[i] = *r.OutputPrice } cacheR[i] = -1 if r.CacheReadPrice != nil { cacheR[i] = *r.CacheReadPrice } cacheW[i] = -1 if r.CacheWritePrice != nil { cacheW[i] = *r.CacheWritePrice } } return db.UpsertAIModelPrices(ctx, database.UpsertAIModelPricesParams{ Providers: providers, Models: models, InputPrices: inputs, OutputPrices: outputs, CacheReadPrices: cacheR, CacheWritePrices: cacheW, }) ``` ### Pros - Single round-trip. ### Cons - The generated `sqlc` params become plain `[]int64`, which can't represent `NULL`. --- ## Approach 3 — `jsonb_array_elements` over a single `@seed::jsonb` (chosen) Pass the raw seed JSON as one parameter; let Postgres expand and parse it. ```sql INSERT INTO ai_model_prices ( provider, model, input_price, output_price, cache_read_price, cache_write_price ) SELECT elem->>'provider', elem->>'model', (elem->>'input_price')::bigint, (elem->>'output_price')::bigint, (elem->>'cache_read_price')::bigint, (elem->>'cache_write_price')::bigint FROM jsonb_array_elements(@seed::jsonb) AS elem ON CONFLICT (provider, model) DO UPDATE SET input_price = EXCLUDED.input_price, output_price = EXCLUDED.output_price, cache_read_price = EXCLUDED.cache_read_price, cache_write_price = EXCLUDED.cache_write_price, updated_at = NOW(); ``` Go side reduces to: ```go return db.UpsertAIModelPrices(ctx, seedJSON) ``` ### Pros - Single round-trip. - NULLs fall out naturally: - `(elem->>'cache_write_price')::bigint` becomes `NULL` - no sentinels - The seed is already JSON: - Existing precedent: - `jsonb_array_elements` is already used elsewhere in the codebase ### Cons - Less type-safe at the SQL boundary than `UNNEST` - Slightly less standard than `UNNEST` - Readers need familiarity with: - `jsonb_array_elements` - `->>` extraction syntax - Postgres pays JSON parse cost - negligible at our scale --- --- # Decision We picked Approach 3. It collapses the round-trips like `UNNEST` does, but without: - nullable-array workarounds - sentinel values |
||
|
|
638e2220e9 |
chore: refactor BuildIcon and remove useClassName (#25017)
|
||
|
|
8d919e5411 | chore: add storybook mcp (#25094) | ||
|
|
3925d3941b |
fix(coderd/x/chatd): wait long enough for cold-start workspace MCP discovery (#25035)
The 5s timeout cancelled cold-start ListMCPTools calls before the agent's 30s connectTimeout could settle, so workspace MCP tools never reached the LLM. Bump to 35s and scope to ListMCPTools only. |
||
|
|
a638f099c8 |
fix(site): show running script count instead of log source count in agent log badge (#25079)
The badge next to the loading spinner in the agent logs section was showing `agent.log_sources.length` (total log sources registered on the agent). This is a static count unrelated to what's actively running. Now it shows the count of startup scripts still in progress: scripts where `run_on_start` is true and `status` is not yet set. Scripts without a `status` haven't completed; completed scripts receive `"ok"`, `"exit_failure"`, `"timed_out"`, or `"pipes_left_open"`. The badge also hides when zero scripts are running. > [!NOTE] > Generated by Coder Agents |
||
|
|
b6dbc5614c |
fix(coderd/x/chatd): handle truncated provider streams (#25074)
coder/fantasy now fails closed when Anthropic or OpenAI Responses streams close before their provider terminal events instead of yielding a successful finish. This bumps the fantasy replacement to coder/fantasy#33 and teaches chat error classification to treat those failures as retryable timeout errors with explicit stream-closed messages. <img width="875" height="311" alt="image" src="https://github.com/user-attachments/assets/69c6f7b5-c885-46d2-a88b-b7a2b111bd55" /> |
||
|
|
de9cdca77e |
fix(coderd): handle external-agent workspaces honestly in chat (#24969)
## Summary Make Coder's chat agent honest about workspaces that use `coder_external_agent`. Three behaviors change so the chat stops pretending it can drive an external workspace through to a usable state on its own. <img width="859" height="537" alt="image" src="https://github.com/user-attachments/assets/0561442b-95f1-4a2d-853c-7e3776114680" /> ## Problem External agents are not started by Coder. The user has to run `coder agent` on their own host with a token Coder generates. Before this change, the chat agent treated those workspaces like any other: - `create_workspace` would enqueue a build for an external-agent template and then wait minutes (~22 worst case) for an agent that was never going to come up. - When mid-turn tool calls dialed an external agent that was not connected, the chat burned the full 30-second dial timeout and returned generic "the workspace may need to be restarted from the Coder dashboard" guidance, which is not the action the user can take. - Nothing told the chat (or the user, through the chat) that the next action lives outside Coder. ## Fix Three changes scoped to `coderd/x/chatd/`: 1. **`create_workspace` blocks templates with external agents.** The tool reads `template_versions.has_external_agent` for the template's active version and refuses external-agent templates with a message instructing the chat to pick a different template, or to have the user create and start the workspace themselves and then attach it. 2. **Attaching an existing external workspace stays open.** No selection-time gate on attachment; users can still bind a working external workspace to a chat. 3. **External-agent-aware error handling on connection.** Two complementary changes both predicated on proven connectivity failures rather than every dial error: - **`getWorkspaceConn` preflight and timeout handling.** Before opening a connection, the cache-miss path reads the agent's status from the already-loaded row. If the selected agent is external and clearly offline according to the existing `isAgentUnreachable` helper (`Disconnected` or `Timeout`, never `Connecting`), it returns an external-agent-specific error immediately instead of waiting out the 30-second dial timeout. `Connecting` external agents fall through to the dial so a user who just started the agent on their host can still succeed in the same turn. The preflight only fires when the agent is still the latest selected agent for the workspace, so stale-binding recovery via `dialWithLazyValidation` is unaffected. The post-dial rewrite is limited to the dial timeout sentinel; stale/no-agent bindings and non-timeout dial failures preserve their original errors. - **`waitForAgentReady` timeout-branch rewrite.** The 2-minute retry loop used by `create_workspace` and `start_workspace` runs unchanged for all agents. When the loop's outer deadline elapses, the timeout branch substitutes the external-agent message in place of the raw dial error if the agent belongs to an external resource. This applies the same pattern that the cache-hit path of `getWorkspaceConn` already used (`isAgentUnreachable` returning `errChatAgentDisconnected`), extended to the cache-miss path and to the readiness helper, with the external-agent-aware error rewrite layered only on confirmed offline or timeout paths. Closes CODAGT-314 |
||
|
|
987d415be3 |
feat(site): show workspace quota failures in chats (#25020)
Create and start workspace tool cards now recognize `INSUFFICIENT_QUOTA` results and use the server-provided quota failure title in the build-log dropdown. The existing warning icon and tooltip remain, while the assistant response remains the place for the detailed recovery guidance. Adds Storybook coverage for quota-reached create and start workspace results. https://github.com/coder/coder/pull/24956 added the necessary backend changes. <img width="897" height="505" alt="image" src="https://github.com/user-attachments/assets/6cab8798-393d-429f-a3c3-a8ed50402d42" /> Closes CODAGT-20 |
||
|
|
3a9080fff6 |
feat: tag chat-originating agent logs with chat_id (#25019)
Workspace-agent logs emitted while serving chatd-driven requests were not correlated with the originating chat, making agent logs hard to attribute to the corresponding/originating chat. This adds agent-side chat context middleware that parses `Coder-Chat-Id` once, enriches agent access logs and structured handler/background logs, and adds a chatd bridge log when chat headers are attached to an agent connection. Closes CODAGT-324 |
||
|
|
e9f0385198 |
docs: update AI Governance label and add v2.32 requirement (#24708)
## Summary Replace the "Premium" label with "AI Governance Add-On" and add a disclaimer that the AI Governance Add-On is required for AI Gateway and Agent Firewall as of Coder v2.32, across all AI Governance doc pages and their children. ## Changes **Label and requirement updates (7 files):** - `docs/ai-coder/ai-governance.md`: Removed "(Premium)" from title; updated GA section to state add-on required as of v2.32. - `docs/ai-coder/ai-gateway/setup.md`: "Premium license" → "AI Governance Add-On license". - `docs/ai-coder/ai-gateway/ai-gateway-proxy/setup.md`: "Premium license" → "AI Governance Add-On". - `docs/ai-coder/ai-gateway/clients/claude-code.md`: "(Premium feature)" → "(AI Governance Add-On)". - `docs/manifest.json`: `"state": ["premium"]` → `"state": ["ai governance add-on"]` for 4 nav entries. **Disclaimer added to all child pages (26 files):** AI Gateway pages (18): `index.md`, `setup.md`, `audit.md`, `monitoring.md`, `mcp.md`, `reference.md`, `ai-gateway-proxy/index.md`, `ai-gateway-proxy/setup.md`, `clients/index.md`, `clients/claude-code.md`, `clients/codex.md`, `clients/mux.md`, `clients/opencode.md`, `clients/factory.md`, `clients/cline.md`, `clients/kilo-code.md`, `clients/roo-code.md`, `clients/vscode.md`, `clients/jetbrains.md`, `clients/zed.md`, `clients/copilot.md` Agent Firewall pages (8): `index.md`, `version.md`, `landjail.md`, `rules-engine.md`, `nsjail/index.md`, `nsjail/docker.md`, `nsjail/k8s.md`, `nsjail/ecs.md` Other: `security.md` > [!NOTE] > The `"ai governance add-on"` state value in `manifest.json` is new. The docs site renderer may need to be updated to support this state value. > Generated by Coder Agents |
||
|
|
400374992c | fix: add pnpm overrides for vulnerable transitive dependencies (#25064) | ||
|
|
9581f76e07 |
fix: add /api prefix to chat swagger annotations (#25051)
Fixes API endpoints in exp_chats.go to ensure the API endpoints show up
correctly.
> 🤖
|
||
|
|
e7958713a9 | feat: add code diff display mode preference (#25027) | ||
|
|
d32842f084 |
feat(site): cycle prompt history with up/down arrows (#25004)
Fixes [CODAGT-319](https://linear.app/codercom/issue/CODAGT-319/support-prompt-history-cycling-with-up-arrow). Pressing the up-arrow key in the agent chat composer now cycles through prior user prompts in the chat (terminal/Discord/iTerm2 style). Down-arrow steps forward, Escape exits cycling and restores the in-progress draft. Cycling is non-destructive: the per-message hover **Edit** button is still the destructive truncate-and-edit path. Replaces the previous up-arrow shortcut that immediately entered destructive history-edit mode (and which had a regression where the composer rendered as "editing" with an empty input box). ## Behaviour - **Up** when composer is empty: snapshot the (empty) draft and load the most recent user prompt; subsequent **Up** presses load older prompts. Clamp at oldest, no wrap. - **Up** while non-empty and not yet cycling: pass through (caret movement preserved). - Once cycling, **Up / Down** are intercepted unconditionally because the cycle text fully replaces editor contents. Exit explicitly via Escape, by sending, or by typing. - **Down** while cycling: load the next-newer prompt, or restore the saved draft when past newest. - **Escape** while cycling: exit cycle and restore the saved draft. This also applies during streaming; the same keypress is stopped before it reaches the interrupt handler, and a second Escape interrupts as before. - **Typing / paste / drop / attach / send / `remountKey` change**: exit cycle mode and clear the snapshot. - Cycling is suppressed while `isEditingHistoryMessage`, `editingQueuedMessageID !== null`, or the input is `disabled` / `isLoading`. - Empty `userPromptHistory` makes Up a no-op (no destructive fallback). ## Out of scope (filed as follow-ups if needed) - Restoring file-reference chips / attachments on cycled messages — v1 cycles plain text only, matching the existing per-message destructive Edit's `text` payload. - `^N` / `^P` keybindings (per Cian's note in the Linear thread). - Per-user "enable/disable history cycling" preference (per Rowan's note). - Cross-chat history; cycling is per-chat. ## Tests New Storybook play functions in `AgentChatInput.stories.tsx`: - `PromptHistoryCycling` — Up cycles older, clamps at oldest; Down returns to newer / draft; Escape restores draft. - `PromptHistoryCyclingExitsOnTyping` — typing exits cycle mode; subsequent Up snapshots the fresh empty draft and Down restores it. - `NoPromptHistoryUpArrowIsNoOp` — empty history → Up is a no-op. - `PromptHistorySuppressedWhileEditingHistoryMessage` — cycling does not engage while history-editing. - `PromptHistorySuppressedWhileDisabled` — cycling does not engage while disabled. - `PromptHistorySuppressedWhileLoading` — cycling does not engage while loading. ## Implementation notes Also rewrites `useImperativeHandle` to delegate to `internalRef.current` lazily on every call instead of capturing it eagerly at factory time. The old code crashed when methods were called after a remount because the captured ref was stale; the new wrapper sees the current Lexical instance. Behavior changes from throw-on-null to silent no-op, which matches every other consumer of `ChatMessageInputRef`. Verified locally: ``` pnpm format pnpm check pnpm test:storybook src/pages/AgentsPage/components/AgentChatInput.stories.tsx # 41 passed pnpm lint ``` ## Manual UAT A 13-case manual UAT covering cycle entry/exit, clamping, draft restoration, no-history no-op, suppression while editing a history message, and the send-button enable state — all PASS. Spec lives at the deleted artifact branch; happy to re-attach if reviewers want it. <details> <summary>Implementation plan and decision log</summary> The complete plan that drove this PR, including design alternatives considered and edge cases: ```md # CODAGT-319 — Up-arrow prompt history cycling ## Goal Pressing the up-arrow key in the agent chat composer should cycle through the user's previously-sent prompts in the current chat, terminal/Discord/iTerm2 style. Down-arrow steps forward; Escape exits cycle mode and restores the in-progress draft. Cycling is non-destructive — it only populates the composer with text the user can choose to resend, edit, or discard. ## Today's behaviour (and the regression) - `ChatMessageInput` is a Lexical-based plain-text editor used inside `AgentChatInput.tsx`. - `AgentChatInput.tsx` already wires an `ArrowUp` handler. When the composer is empty and not already editing, it calls `onEditLastUserMessage`. - `onEditLastUserMessage` puts the user into a destructive "edit history" mode that warns "Editing will delete all subsequent messages and restart the conversation here.". - Danielle's regression report ("shows me as editing but the input box is empty") indicates the destructive flow has a bug in addition to being the wrong UX for the request. We're replacing that path on the up-arrow, not patching it. The destructive edit remains accessible via the per-message hover Edit button. ## Design ### Behaviour - Up when composer is empty: snapshot the (empty) draft and load the most recent user prompt. Subsequent Up loads older prompts, clamping at oldest. No wrap. - Up while non-empty and not yet cycling: pass through. Matches existing gating. - Once cycling, Up/Down are intercepted unconditionally. Exit via Escape, send, or typing. - Down while cycling: next-newer or restore draft past newest. - Escape while cycling: restore draft. During streaming, stop propagation so the same keypress does not interrupt; a second Escape interrupts as before. - Typing/paste/drop/attach/send: exit cycle. - Suppressed while isEditingHistoryMessage, editingQueuedMessageID !== null, or disabled/isLoading. - No history => Up is a no-op. ### State Local to `AgentChatInput.tsx`: - `cycleIndex: number | null` — null means not cycling. 0 = newest user prompt. - `cycleSavedDraft: string | null` — text restored on dismiss. No localStorage persistence — refresh is a clean exit signal and the chat already has history server-side. ### Wiring - New prop `userPromptHistory: readonly string[]` on `AgentChatInput`, newest-first. - Removed `onEditLastUserMessage` prop entirely (its single call-site is being replaced). Removed dead `onEditUserMessage` prop on `ChatPageInput` (no longer needed since the destructive last-message shortcut is gone; the destructive Edit button uses a separate prop chain through `ChatPageTimeline`). - `ChatPageContent.tsx` derives `userPromptHistory` from existing message store, filtered to `role === "user"` with non-empty `getEditableUserMessagePayload(message).text.trim()`. ### Reset triggers `cycleIndex` and `cycleSavedDraft` reset on: 1. New `remountKey` (chat change, edit start/cancel). 2. Successful send. 3. Paste, drop, file attach. 4. User typing (detected via `handleContentChange` by comparing the incoming content to `currentCycleValueRef`, the last value applied programmatically). ### Out of scope - Chip/attachment cycling. - ^N/^P (Cian's note). - Per-user toggle (Rowan's note). - Cross-chat history. ``` </details> --- > [!NOTE] > This PR was created on behalf of @ibetitsmike by Coder Agents. --------- Co-authored-by: Coder Agents <noreply@coder.com> |
||
|
|
ffe2595f63 | fix: scan coder-preview:main instead of coder:latest (#25056) | ||
|
|
39789c5c3b |
chore: bump uuid from 11.1.1 to 14.0.0 in /site (#24653)
Bumps [uuid](https://github.com/uuidjs/uuid) from 11.1.1 to 14.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/uuidjs/uuid/releases">uuid's releases</a>.</em></p> <blockquote> <h2>v14.0.0</h2> <h2><a href="https://github.com/uuidjs/uuid/compare/v13.0.0...v14.0.0">14.0.0</a> (2026-04-19)</h2> <h3>⚠ BREAKING CHANGES</h3> <ul> <li>expect <code>crypto</code> to be global everywhere (requires node@20+) (<a href="https://redirect.github.com/uuidjs/uuid/issues/935">#935</a>)</li> <li>drop node@18 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/934">#934</a>)</li> </ul> <h3>Features</h3> <ul> <li>drop node@18 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/934">#934</a>) (<a href="https://github.com/uuidjs/uuid/commit/dc4ddb87272ed2843faccd130bcc41d492688bd3">dc4ddb8</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>expect <code>crypto</code> to be global everywhere (requires node@20+) (<a href="https://redirect.github.com/uuidjs/uuid/issues/935">#935</a>) (<a href="https://github.com/uuidjs/uuid/commit/f2c235f93059325fa43e1106e624b5291bb523c4">f2c235f</a>)</li> <li>Use GITHUB_TOKEN for release-please and enable npm provenance (<a href="https://redirect.github.com/uuidjs/uuid/issues/925">#925</a>) (<a href="https://github.com/uuidjs/uuid/commit/ffa31383e8e4e1f0b4e22e504561272041b8738c">ffa3138</a>)</li> </ul> <h2>v13.0.2</h2> <h2><a href="https://github.com/uuidjs/uuid/compare/v13.0.1...v13.0.2">13.0.2</a> (2026-05-04)</h2> <h3>Bug Fixes</h3> <ul> <li>rerelease to fix provenance. (<a href="https://github.com/uuidjs/uuid/commit/49ccb35f78c0c4ce1409dd2f1d89f83caadba10b">49ccb35</a>)</li> </ul> <h2>v13.0.1</h2> <h2><a href="https://github.com/uuidjs/uuid/compare/v13.0.0...v13.0.1">13.0.1</a> (2026-04-27)</h2> <h3>Bug Fixes</h3> <ul> <li>backport fix for GHSA-w5hq-g745-h8pq (<a href="https://github.com/uuidjs/uuid/commit/9d27ddf7046ce496ef39569ff84d948eeff9cb2a">9d27ddf</a>)</li> </ul> <h2>v13.0.0</h2> <h2><a href="https://github.com/uuidjs/uuid/compare/v12.0.0...v13.0.0">13.0.0</a> (2025-09-08)</h2> <h3>⚠ BREAKING CHANGES</h3> <ul> <li>make browser exports the default (<a href="https://redirect.github.com/uuidjs/uuid/issues/901">#901</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>make browser exports the default (<a href="https://redirect.github.com/uuidjs/uuid/issues/901">#901</a>) (<a href="https://github.com/uuidjs/uuid/commit/bce9d72a3ae5b9a3dcd8eb21ef6d1820288a427a">bce9d72</a>)</li> </ul> <h2>v12.0.1</h2> <h2><a href="https://github.com/uuidjs/uuid/compare/v12.0.0...v12.0.1">12.0.1</a> (2026-04-29)</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md">uuid's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/uuidjs/uuid/compare/v13.0.0...v14.0.0">14.0.0</a> (2026-04-19)</h2> <h3>Security</h3> <ul> <li>Fixes <a href="https://github.com/uuidjs/uuid/security/advisories/GHSA-w5hq-g745-h8pq">GHSA-w5hq-g745-h8pq</a>: <code>v3()</code>, <code>v5()</code>, and <code>v6()</code> did not validate that writes would remain within the bounds of a caller-supplied buffer, allowing out-of-bounds writes when an invalid <code>offset</code> was provided. A <code>RangeError</code> is now thrown if <code>offset < 0</code> or <code>offset + 16 > buf.length</code>.</li> </ul> <h3>⚠ BREAKING CHANGES</h3> <ul> <li><code>crypto</code> is now expected to be globally defined (requires node@20+) (<a href="https://redirect.github.com/uuidjs/uuid/issues/935">#935</a>)</li> <li>drop node@18 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/934">#934</a>)</li> <li>upgrade minimum supported TypeScript version to 5.4.3, in keeping with the project's policy of supporting TypeScript versions released within the last two years</li> </ul> <h2><a href="https://github.com/uuidjs/uuid/compare/v12.0.0...v13.0.0">13.0.0</a> (2025-09-08)</h2> <h3>⚠ BREAKING CHANGES</h3> <ul> <li>make browser exports the default (<a href="https://redirect.github.com/uuidjs/uuid/issues/901">#901</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>make browser exports the default (<a href="https://redirect.github.com/uuidjs/uuid/issues/901">#901</a>) (<a href="https://github.com/uuidjs/uuid/commit/bce9d72a3ae5b9a3dcd8eb21ef6d1820288a427a">bce9d72</a>)</li> </ul> <h2><a href="https://github.com/uuidjs/uuid/compare/v11.1.0...v12.0.0">12.0.0</a> (2025-09-05)</h2> <h3>⚠ BREAKING CHANGES</h3> <ul> <li>update to typescript@5.2 (<a href="https://redirect.github.com/uuidjs/uuid/issues/887">#887</a>)</li> <li>remove CommonJS support (<a href="https://redirect.github.com/uuidjs/uuid/issues/886">#886</a>)</li> <li>drop node@16 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/883">#883</a>)</li> </ul> <h3>Features</h3> <ul> <li>add node@24 to ci matrix (<a href="https://redirect.github.com/uuidjs/uuid/issues/879">#879</a>) (<a href="https://github.com/uuidjs/uuid/commit/42b6178aa21a593257f0a72abacd220f0b7b8a92">42b6178</a>)</li> <li>drop node@16 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/883">#883</a>) (<a href="https://github.com/uuidjs/uuid/commit/0f38cf10366ab074f9328ae2021eea04d5f2e530">0f38cf1</a>)</li> <li>remove CommonJS support (<a href="https://redirect.github.com/uuidjs/uuid/issues/886">#886</a>) (<a href="https://github.com/uuidjs/uuid/commit/ae786e27265f50bcf7cead196c29f1869297c42f">ae786e2</a>)</li> <li>update to typescript@5.2 (<a href="https://redirect.github.com/uuidjs/uuid/issues/887">#887</a>) (<a href="https://github.com/uuidjs/uuid/commit/c7ee40598ed78584d81ab78dffded9fe5ff20b01">c7ee405</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>improve v4() performance (<a href="https://redirect.github.com/uuidjs/uuid/issues/894">#894</a>) (<a href="https://github.com/uuidjs/uuid/commit/5fd974c12718c8848035650b69b8948f12ace197">5fd974c</a>)</li> <li>restore node: prefix (<a href="https://redirect.github.com/uuidjs/uuid/issues/889">#889</a>) (<a href="https://github.com/uuidjs/uuid/commit/e1f42a354593093ba0479f0b4047dae82d28c507">e1f42a3</a>)</li> </ul> <h2><a href="https://github.com/uuidjs/uuid/compare/v11.0.5...v11.1.0">11.1.0</a> (2025-02-19)</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/uuidjs/uuid/commit/7c1ea087a8149b57380fc8bb7f68c3a215cb6e4b"><code>7c1ea08</code></a> chore(main): release 14.0.0 (<a href="https://redirect.github.com/uuidjs/uuid/issues/926">#926</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/3d2c5b0342f0fcb52a5ac681c3d47c13e7444b34"><code>3d2c5b0</code></a> Merge commit from fork</li> <li><a href="https://github.com/uuidjs/uuid/commit/f2c235f93059325fa43e1106e624b5291bb523c4"><code>f2c235f</code></a> fix!: expect <code>crypto</code> to be global everywhere (requires node@20+) (<a href="https://redirect.github.com/uuidjs/uuid/issues/935">#935</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/529ef0899f5dd503d2ee90d690585d63d78bc212"><code>529ef08</code></a> chore: upgrade TypeScript and fixup types (<a href="https://redirect.github.com/uuidjs/uuid/issues/927">#927</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/086fd7976f11433edf9ac80be876b3ad243fe087"><code>086fd79</code></a> chore: update dependencies (<a href="https://redirect.github.com/uuidjs/uuid/issues/933">#933</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/dc4ddb87272ed2843faccd130bcc41d492688bd3"><code>dc4ddb8</code></a> feat!: drop node@18 support (<a href="https://redirect.github.com/uuidjs/uuid/issues/934">#934</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/0f1f9c9c9cedbae5a1d363d5406c5dfbabe81404"><code>0f1f9c9</code></a> chore: switch to Biome for parsing and linting (<a href="https://redirect.github.com/uuidjs/uuid/issues/932">#932</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/e2879e64bf125add903c1eff6e0860542c605013"><code>e2879e6</code></a> chore: use maintained version of npm-run-all (<a href="https://redirect.github.com/uuidjs/uuid/issues/930">#930</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/ffa31383e8e4e1f0b4e22e504561272041b8738c"><code>ffa3138</code></a> fix: Use GITHUB_TOKEN for release-please and enable npm provenance (<a href="https://redirect.github.com/uuidjs/uuid/issues/925">#925</a>)</li> <li><a href="https://github.com/uuidjs/uuid/commit/0423d49df2dc8efc300c804731d25f4d7e0fccc4"><code>0423d49</code></a> docs: remove obsolete v1 option notes (<a href="https://redirect.github.com/uuidjs/uuid/issues/915">#915</a>)</li> <li>Additional commits viewable in <a href="https://github.com/uuidjs/uuid/compare/v11.1.1...v14.0.0">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> |
||
|
|
528196483b | chore: override transitive dependency versions for offlinedocs (#25050) | ||
|
|
be5753dd63 | chore: pin overrides in site/package.json (#25052) | ||
|
|
6c3bf80892 |
docs(docs/admin/users/oidc-auth): note SCIM 2.0 support is not guaranteed (#25008)
Adds an `[!IMPORTANT]` callout under the SCIM heading in the OIDC auth docs noting that Coder's SCIM 2.0 implementation is not a fully certified or guaranteed implementation of the spec. It covers common provisioning/deprovisioning flows with major IdPs (Okta, Entra ID, etc.) but specific attributes, endpoints, or behaviors may not be supported and may change between releases. This matches what we say in conversations with prospects and avoids setting an expectation we can't always meet. Background: #15830 (current implementation is an MVP scoped to Okta cloud; `PATCH` is not RFC 7644 compliant; user updates only change status, not groups/orgs/roles). Companion PR: coder/coder.com#738 removes the SCIM row from the pricing comparison. > Generated with [Coder Agents](https://coder.com/agents) |
||
|
|
9fd2cc78fe | refactor(site): migrate more styles from emotion to tailwind (#24914) | ||
|
|
89034f6422 |
test(coderd/database): cover step message ID boundaries (#24690)
Closes #24091 Adds `TestDeleteChatDebugDataAfterMessageIDStepLevelFieldBoundariesAndNulls`, which complements the existing triggered-runs test for `DeleteChatDebugDataAfterMessageID` with boundary and NULL coverage for step-level message IDs. The existing `TestDeleteChatDebugDataAfterMessageIDIncludesTriggeredRuns` already exercises the `step.assistant_message_id > @message_id` deletion path. This test focuses on: - Strict greater-than behavior at the cutoff for assistant and history-tip step message IDs. - Step-level assistant and history-tip message ID combinations. - SQL NULL behavior for step-level message IDs. - A mixed-step run where one matching step deletes the whole run and cascades every step. | Scenario | assistant_message_id | history_tip_message_id | Expected | |----------|----------------------|------------------------|----------| | Assistant above cutoff, history tip NULL | cutoff + 5 | NULL | Deleted | | Assistant above cutoff, history tip below cutoff | cutoff + 20 | cutoff - 3 | Deleted | | Assistant below cutoff, history tip NULL | cutoff - 3 | NULL | Preserved | | Assistant at cutoff boundary, history tip NULL | cutoff | NULL | Preserved | | Assistant NULL, history tip above cutoff | NULL | cutoff + 2 | Deleted | | Assistant NULL, history tip at cutoff boundary | NULL | cutoff | Preserved | | Both step message IDs NULL | NULL | NULL | Preserved | > Generated by Coder Agents <details><summary>Review notes</summary> - Run-level message IDs are below the cutoff to isolate step-level selection. - The assistant-above-cutoff scenario includes a second nonmatching step to cover mixed-step deletion. - The test uses unique model and chat names for isolation. - `go test -v ./coderd/database -run TestDeleteChatDebugDataAfterMessageID -count=1` passes. </details> |
||
|
|
6d633a0283 |
chore: bump react-router from 7.9.6 to 7.12.0 in /site (#25048)
Bumps [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) from 7.9.6 to 7.12.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/remix-run/react-router/releases">react-router's releases</a>.</em></p> <blockquote> <h2>v7.12.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7120">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7120</a></p> <h2>v7.11.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7110">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7110</a></p> <h2>v7.10.1</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7101">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7101</a></p> <h2>v7.10.0</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7100">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v7100</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md">react-router's changelog</a>.</em></p> <blockquote> <h2>7.12.0</h2> <h3>Minor Changes</h3> <ul> <li>Add additional layer of CSRF protection by rejecting submissions to UI routes from external origins. If you need to permit access to specific external origins, you can specify them in the <code>react-router.config.ts</code> config <code>allowedActionOrigins</code> field. (<a href="https://redirect.github.com/remix-run/react-router/pull/14708">#14708</a>)</li> </ul> <h3>Patch Changes</h3> <ul> <li> <p>Fix <code>generatePath</code> when used with suffixed params (i.e., "/books/:id.json") (<a href="https://redirect.github.com/remix-run/react-router/pull/14269">#14269</a>)</p> </li> <li> <p>Export <code>UNSAFE_createMemoryHistory</code> and <code>UNSAFE_createHashHistory</code> alongside <code>UNSAFE_createBrowserHistory</code> for consistency. These are not intended to be used for new apps but intended to help apps usiong <code>unstable_HistoryRouter</code> migrate from v6->v7 so they can adopt the newer APIs. (<a href="https://redirect.github.com/remix-run/react-router/pull/14663">#14663</a>)</p> </li> <li> <p>Escape HTML in scroll restoration keys (<a href="https://redirect.github.com/remix-run/react-router/pull/14705">#14705</a>)</p> </li> <li> <p>Validate redirect locations (<a href="https://redirect.github.com/remix-run/react-router/pull/14706">#14706</a>)</p> </li> <li> <p>[UNSTABLE] Pass <code><Scripts nonce></code> value through to the underlying <code>importmap</code> <code>script</code> tag when using <code>future.unstable_subResourceIntegrity</code> (<a href="https://redirect.github.com/remix-run/react-router/pull/14675">#14675</a>)</p> </li> <li> <p>[UNSTABLE] Add a new <code>future.unstable_trailingSlashAwareDataRequests</code> flag to provide consistent behavior of <code>request.pathname</code> inside <code>middleware</code>, <code>loader</code>, and <code>action</code> functions on document and data requests when a trailing slash is present in the browser URL. (<a href="https://redirect.github.com/remix-run/react-router/pull/14644">#14644</a>)</p> <p>Currently, your HTTP and <code>request</code> pathnames would be as follows for <code>/a/b/c</code> and <code>/a/b/c/</code></p> <table> <thead> <tr> <th>URL <code>/a/b/c</code></th> <th><strong>HTTP pathname</strong></th> <th><strong><code>request</code> pathname`</strong></th> </tr> </thead> <tbody> <tr> <td><strong>Document</strong></td> <td><code>/a/b/c</code></td> <td><code>/a/b/c</code> ✅</td> </tr> <tr> <td><strong>Data</strong></td> <td><code>/a/b/c.data</code></td> <td><code>/a/b/c</code> ✅</td> </tr> </tbody> </table> <table> <thead> <tr> <th>URL <code>/a/b/c/</code></th> <th><strong>HTTP pathname</strong></th> <th><strong><code>request</code> pathname`</strong></th> </tr> </thead> <tbody> <tr> <td><strong>Document</strong></td> <td><code>/a/b/c/</code></td> <td><code>/a/b/c/</code> ✅</td> </tr> <tr> <td><strong>Data</strong></td> <td><code>/a/b/c.data</code></td> <td><code>/a/b/c</code> ⚠️</td> </tr> </tbody> </table> <p>With this flag enabled, these pathnames will be made consistent though a new <code>_.data</code> format for client-side <code>.data</code> requests:</p> <table> <thead> <tr> <th>URL <code>/a/b/c</code></th> <th><strong>HTTP pathname</strong></th> <th><strong><code>request</code> pathname`</strong></th> </tr> </thead> <tbody> <tr> <td><strong>Document</strong></td> <td><code>/a/b/c</code></td> <td><code>/a/b/c</code> ✅</td> </tr> <tr> <td><strong>Data</strong></td> <td><code>/a/b/c.data</code></td> <td><code>/a/b/c</code> ✅</td> </tr> </tbody> </table> <table> <thead> <tr> <th>URL <code>/a/b/c/</code></th> <th><strong>HTTP pathname</strong></th> <th><strong><code>request</code> pathname`</strong></th> </tr> </thead> <tbody> <tr> <td><strong>Document</strong></td> <td><code>/a/b/c/</code></td> <td><code>/a/b/c/</code> ✅</td> </tr> <tr> <td><strong>Data</strong></td> <td><code>/a/b/c/_.data</code> ⬅️</td> <td><code>/a/b/c/</code> ✅</td> </tr> </tbody> </table> <p>This a bug fix but we are putting it behind an opt-in flag because it has the potential to be a "breaking bug fix" if you are relying on the URL format for any other application or caching logic.</p> <p>Enabling this flag also changes the format of client side <code>.data</code> requests from <code>/_root.data</code> to <code>/_.data</code> when navigating to <code>/</code> to align with the new format. This does not impact the <code>request</code> pathname which is still <code>/</code> in all cases.</p> </li> <li> <p>Preserve <code>clientLoader.hydrate=true</code> when using <code><HydratedRouter unstable_instrumentations></code> (<a href="https://redirect.github.com/remix-run/react-router/pull/14674">#14674</a>)</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/remix-run/react-router/commit/26653a6bcbf8a9c5541f99dcfb526eafadf13434"><code>26653a6</code></a> chore: Update version for release (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14712">#14712</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/7ac2346873b4bba26d16c88e5cd5c5cb81ce6bb3"><code>7ac2346</code></a> chore: Update version for release (pre) (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14709">#14709</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/75b1ef50867d8fa3d5ffdab28245d5fec307d6a7"><code>75b1ef5</code></a> Add origin checks for UI route submissions (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14708">#14708</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/c05ef936fd9334f82aafa7e9087b78a8bf5c745d"><code>c05ef93</code></a> Validate redirect locations (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14706">#14706</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/c89c32c562a7723c45ee71dab1c892acaf7a608d"><code>c89c32c</code></a> Escape HTML in scroll restoration keys (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14705">#14705</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/cbcbf3091b55ef0067724fbd744f31c6d85eb1e6"><code>cbcbf30</code></a> fix: pass nonce to importmap script when using subResourceIntegrity (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14675">#14675</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/30f6c1d8142cbd2c26aef57cb2e12a4a8708eb4f"><code>30f6c1d</code></a> fix(react-router): handle parameters with static suffixes in generatePath (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/1">#1</a>...</li> <li><a href="https://github.com/remix-run/react-router/commit/7f140e098ecd83fd183468e0c0acae86589bfd11"><code>7f140e0</code></a> Handle data requests with trailing slash consistently (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14644">#14644</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/1954af63742be277162f8d5d054ca07e04a4a401"><code>1954af6</code></a> Preserve hydrate property on client loaders during instrumentation (<a href="https://github.com/remix-run/react-router/tree/HEAD/packages/react-router/issues/14674">#14674</a>)</li> <li><a href="https://github.com/remix-run/react-router/commit/5ce5cd4ebfc6959bf8d667075cb5b9ae0a9d5476"><code>5ce5cd4</code></a> chore: format</li> <li>Additional commits viewable in <a href="https://github.com/remix-run/react-router/commits/react-router@7.12.0/packages/react-router">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/coder/coder/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
87d580d3fe |
fix(coderd/taskname): parse task name JSON with trailing text (#25005)
Anthropic task name responses can include valid JSON followed by a closing fence or extra text, which made `json.Unmarshal` fail with trailing-character errors and forced fallback naming. This updates task name JSON extraction to accept the first JSON value after optional fences and adds regression coverage for fenced and bare JSON with trailing content. |
||
|
|
e1b1c7ec5b |
feat: resize chat image attachments client-side for provider budgets (#24533)
Anthropic rejects inline images over 5,242,880 bytes, but our upload endpoint accepts images up to 10 MiB — so 5–10 MiB images were reaching the provider and failing. This adds two layers of protection: the browser resizes oversized images before upload, and the server rejects any that still slip through before an upstream request is issued. Client-side resizing uses `createImageBitmap` with `resizeWidth`/`resizeHeight` to clamp the decoded bitmap at decode time, then iteratively shrinks on an `OffscreenCanvas` (falling back to `HTMLCanvasElement`) until the output fits the applicable budget. Anthropic (and Bedrock-hosted Claude — fantasy's bedrock provider is a thin wrapper around the Anthropic client) uses a ~5 MiB budget; other providers use a ~10 MiB budget to stay under the server cap. Doing the resize in the browser avoids decoding attacker-controlled image bytes in `coderd` (image-bomb DoS surface). Server-side, `chatFileResolver` now takes a provider string and looks up the inline-image cap via a new `chatprovider.InlineImageByteCap` helper; oversized `image/*` files for capped providers are rejected with a pre-classified `chaterror` before the SDK call. The backstop fires for older clients, direct API callers, or any image that was committed to the composer before the user switched to a stricter provider. Attachments commit to composer state synchronously with a new `"processing"` `UploadState` so paste+Enter can't dispatch before the resize finishes; the `"uploading"` send gate now covers both states. Dismissed-while-resizing attachments are tracked in a `WeakSet` so a late swap can't resurrect a removed file. Closes CODAGT-215 |
||
|
|
eef09f3d98 | chore: update terraform to v1.15.2 (#25045) | ||
|
|
03c5ae3f70 |
test(coderd/database): enhance FinalizeStaleChatDebugRows integration test (#24693)
Closes #24090 Enhances the existing `TestFinalizeStaleChatDebugRows` test with three missing coverage areas: 1. **Error JSON preservation**: verifies pre-existing error payloads are not overwritten by finalization 2. **Timestamp correctness**: verifies `updated_at` and `finished_at` match the `@now` parameter across all finalized row paths 3. **Null error preservation**: verifies finalized steps that had no error keep a null error column No production code changed. Test passes against Postgres. > 🤖 Generated by Coder Agents <details><summary>Review notes</summary> - Enhances existing test rather than adding a new one, the existing test was the right place - Covers stale, orphaned, and cascade finalization timestamp assertions - Preserves both pre-existing error JSON and null error values during finalization </details> |
||
|
|
0766cc3097 |
feat: add automatic key failover for AI Bridge passthrough (#24920)
## Description Adds automatic key failover for passthrough routes for the Anthropic and OpenAI providers. A new `keyFailoverTransport` wraps the reverse-proxy transport: centralized requests walk the configured key pool and retry with the next key on key-specific failures (401/403/429), reusing the same key-marking semantics as the bridged routes. BYOK passthrough requests run as a single attempt with no failover. ## Changes - New `keypool.KeyFailoverConfig` carrying the `Pool` to walk and the provider-specific closures (`IsBYOK`, `InjectAuthKey`, `MarkKey`, `BuildExhaustedResponse`). - New `keypool.NewKeyFailoverTransport`: wraps an inner `http.RoundTripper`. Returns `inner` unchanged when `Pool` is nil, otherwise produces a transport that buffers the request body once, walks the pool per request, and replays each attempt with the next key. - New `Provider.KeyFailoverConfig(logger)` interface method. Anthropic injects `X-Api-Key`; OpenAI injects `Authorization: Bearer ...`; Copilot returns an empty config. - `passthrough.go` wires `NewKeyFailoverTransport` around the existing apidump middleware, so every retry attempt is recorded. ## Related Issues Related to: https://github.com/coder/internal/issues/1446 Related to: https://linear.app/codercom/issue/AIGOV-197/aibridge-automatic-key-failover-for-bridged-and-passthrough-routes ## Follow-up PRs - Remove dead `Provider.InjectAuthHeader` method now that all auth is applied per-attempt by `KeyFailoverTransport`. - Bedrock multi-key support. - Refactor provider vs interceptor config separation. - Record the actually-used key in the interception credential hint after failover. > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
b94a0aebcd |
fix(coderd/externalauth): isolate TestValidateToken transports to fix flake (#25015)
This change uses separate http clients/transports in TestValidateToken subtests. Previously parallel subtests of TestValidateToken shared a http.DefaultTransport. When one subtest's httptest.Server.Close() ran in t.Cleanup, it called http.DefaultTransport.CloseIdleConnections, which could interrupt connection(s) used in another subtest. |
||
|
|
b6dacb4a3c |
feat: add automatic key failover for AI Bridge OpenAI (#24847)
## Description Adds automatic key failover for centralized OpenAI provider, covering both chat completions and responses APIs. Same shape as the Anthropic PR: each upstream call walks the configured key pool, keys are marked **temporary** on 429 (with cooldown from `Retry-After`) and **permanent** on 401/403. Each agentic-loop iteration gets its own fresh walker so a tool-call continuation can fail over independently of the initial request. BYOK is unchanged: BYOK requests run as a single attempt with no failover. ## Changes - `config.OpenAI` carries a `KeyPool`. `Key` remains for BYOK Authorization Bearer set per interception. - Chat completions blocking interceptor: walks the pool via `newChatCompletionWithKeyFailover`, marks keys on key-specific failures, returns on first success or non-failover error. - Chat completions streaming interceptor: per-iteration walker. Pre-stream failures fail over to the next key; mid-stream errors are relayed as SSE events. - Responses blocking interceptor: extracts `newResponseWithKeyFailover` parallel to chatcompletions. - Responses streaming interceptor: per-iteration walker, retains the existing buffer-then-forward design. ## Related Issues Related to: https://github.com/coder/internal/issues/1446 Related to: https://linear.app/codercom/issue/AIGOV-197/aibridge-automatic-key-failover-for-bridged-and-passthrough-routes ## Follow-up PRs - Bedrock multi-key support. - Refactor provider vs interceptor config separation. - Record the actually-used key in the interception credential hint after failover. > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
f1155ac4d7 |
feat: add automatic key failover for AI Bridge Anthropic (#24836)
## Description Adds automatic key failover for centralized Anthropic provider. When a key pool is configured, each upstream call walks the pool and tries keys in order until one succeeds or the pool is exhausted. Keys are marked **temporary** on 429 (with cooldown from `Retry-After`) and **permanent** on 401/403. Errors that aren't key-specific don't trigger failover. Each agentic-loop iteration gets its own fresh walker, so a tool-call continuation can fail over independently of the initial request. BYOK is unchanged: BYOK requests run as a single attempt with no failover. ## Changes - `config.Anthropic` carries a `KeyPool`. `Key` remains for BYOK X-Api-Key set per interception. - Blocking interceptor: walks the pool, marks keys on key-specific failures, returns on first success or non-failover error. - Streaming interceptor: per-iteration walker. Pre-stream failures fail over to the next key; mid-stream errors are relayed as SSE events. - New `keypool` error types: `TransientExhaustionError` (carries soonest cooldown) and `ErrPermanentExhaustion`. Replace the prior `ErrAllKeysExhausted`. - Error responses now consistently include the outer `"type": "error"` field. ## Related Issues Related to: https://github.com/coder/internal/issues/1446 Related to: https://linear.app/codercom/issue/AIGOV-197/aibridge-automatic-key-failover-for-bridged-and-passthrough-routes ## Follow-up PRs - Bedrock multi-key support. - Refactor provider vs interceptor config separation. - Record the actually-used key in the interception credential hint after failover. > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
273e828442 | fix: remove advisor reasoning configuration (#25030) | ||
|
|
8c08aa1f6c |
fix(coderd/x/chatd): wake after async chat-row UPDATEs commit (#25036)
The async title-generation and turn-summary goroutines launched from processChat run autocommit UPDATEs on the chat row after finishActiveChat has set the chat to pending and signalWake has fired. If the row lock from one of those UPDATEs is held while acquireLoop's processOnce runs, AcquireChats's FOR UPDATE SKIP LOCKED skips the freshly-pending chat and returns no rows. The wake is then consumed with no acquisition, and the chat sits in pending until the next acquireTicker (default 1s). Wake again after each UPDATE commits. The second wake covers the race window without changing the transaction semantics. Closes coder/internal#1500 |
||
|
|
20453e123e | fix(site): clamp lander position on landing to keep feet on pad (#25026) | ||
|
|
1564f2d745 |
chore: pin Docker 27 on dogfood Ubuntu 26.04 image (#25028)
## Summary - switch the Ubuntu 26.04 dogfood image to Docker's jammy apt repository so Docker 27 remains available - pin `docker-ce` and `docker-ce-cli` to the Docker 27 line and keep `containerd.io` pinned to `1.7.23-1` - fold the containerd pin into the Docker preferences file, remove the duplicate containerd preferences file, and hold the installed Docker packages in the image ## Notes Docker 28+ requires `containerd.io >= 1.7.27`, but sysbox / Docker-in-Docker currently requires `containerd.io=1.7.23-1`, so the image needs the older Docker 27 packages from the jammy repo. ## Testing - Not run locally; verified the branch diff only. |
||
|
|
9ec2df9574 |
feat(site/src/pages/AgentsPage): resize agents sidebar (#24963)
Adds a persisted, draggable left sidebar width for the agents page. The resize handle uses the same pointer-capture resize technique as the existing right panel and clamps the expanded sidebar between 240px and `min(520px, 50vw)`. Updates the agents page skeleton to read the same stored sidebar width and adds Storybook interaction coverage for resize clamping and persistence. |
||
|
|
10a22a4753 |
fix(site/src/pages/AgentsPage): polish advisor UI (#25002)
Polishes the advisor tool card so the header uses a clearer lightbulb icon, inline pill metadata, wrapped/clamped question text, and a separate advice pill before the rendered response. Adds Storybook coverage for a long advice plus 1.8k-character question peak state, including collapse/expand behavior. Refs https://linear.app/codercom/issue/CODAGT-322/improve-advisor-icon-and-duplicate-loading-ui <details> <summary>Coder Agents disclosure</summary> This PR was generated by Coder Agents. </details> |
||
|
|
6fa7e84761 |
test(coderd/x/chatd): skip TestExploreChatSendMessageCannotMutateMCPSnapshot (#25023)
Skips `TestExploreChatSendMessageCannotMutateMCPSnapshot` while the chatd redesign is in flight. The test exposes a self-interrupt race in `processChat`'s control-pubsub subscriber that is structurally fixed by the redesign in #24444; skipping until then matches the existing `TestSubscribeRelayEstablishedMidStream` skip in `enterprise/coderd/x/chatd/chatd_test.go`. Relates to https://github.com/coder/internal/issues/1493. |
||
|
|
f605d6bcb4 |
feat(dogfood/coder): add brew and mise to ubuntu images (#24618)
This adds Homebrew and mise to the Ubuntu dogfood images and makes mise shims win PATH resolution for the `coder` user. It installs Homebrew in `/home/linuxbrew/.linuxbrew`, installs the latest mise release (`v2026.4.19`) via its verified GitHub release artifact, exposes mise at `/usr/local/bin/mise`, wires `HOMEBREW_*` and `MISE_DATA_DIR`, and adds build-time checks for both tools. The mise executable target lives in writable `/opt/mise/bin` so `mise self-update` can replace it as the `coder` user. This also adds `libc6-dev` to the Go utility stages so the existing CGO-backed tool installs keep building on newer Ubuntu bases. The dogfood template now mounts a dedicated `/home/linuxbrew/` Docker volume in addition to `/home/coder/`. Fresh volumes are seeded from the image-baked Homebrew tree on first mount, while user-installed formulae persist across workspace container recreation. I revalidated the bootstrap on jammy and resolute base images with fresh mounted `/home/coder` and `/home/linuxbrew` volumes. In those runs, `brew install hello` succeeded, `mise doctor` reported no PATH or activation problems, `mise self-update --force --yes --no-plugins 2026.4.19` succeeded as `coder`, and `mise use --global github:BurntSushi/ripgrep@14.1.1` moved `rg` resolution to the mise shim after container recreation. --- <details> <summary>📋 Implementation Plan</summary> # Plan: add `mise` and Homebrew to the dogfood Ubuntu images with mise-first PATH ## Goal - Make both dogfood Ubuntu images ship `brew` and `mise`. - Ensure `mise doctor` does **not** complain about activation/PATH ordering in the shell entrypoints we support. - Keep the implementation robust against the persistent `/home/coder` volume used by the dogfood template. ## Verified context - The relevant image definitions are: - `dogfood/coder/ubuntu-22.04/Dockerfile` - `dogfood/coder/ubuntu-26.04/Dockerfile` - The dogfood template mounts a persistent home volume at `/home/coder/` in `dogfood/coder/main.tf:840-843`, so required image-baked state should not live only under `/home/coder`. - Both Dockerfiles already manipulate PATH in multiple places: - Go appended early (`:26`) - Cargo prepended (`ubuntu-26.04/Dockerfile:202-206`; mirrored in 22.04) - Node via nvm prepended (`ubuntu-26.04/Dockerfile:245-255`; mirrored in 22.04) - Final `coder` PATH prepends `/home/coder/go/bin` (`ubuntu-26.04/Dockerfile:348-358`; mirrored in 22.04) - `COPY files /` is already present in both Dockerfiles, so adding new global shell-init files is possible without Terraform changes. - `scripts/lib.sh:94-124` uses `command -v` for dependency detection, so PATH order is the practical repo-level behavior we need to control. - `.github/workflows/dogfood.yaml:99-126` builds both Ubuntu variants, and the 22.04 image is still tagged `latest`, so both Dockerfiles must be updated in the same change. ## Recommended implementation ### Phase 1 — Bootstrap Homebrew and `mise` in both Ubuntu Dockerfiles 1. Update both Dockerfiles in parallel: - `dogfood/coder/ubuntu-22.04/Dockerfile` - `dogfood/coder/ubuntu-26.04/Dockerfile` 2. Add the minimum explicit Homebrew prerequisites that are missing from the current apt package set. - The images already install `build-essential`, `curl`, `file`, and `git`. - Audit whether `procps` must be added explicitly for Homebrew’s Linux requirements. 3. Install Homebrew in the supported Linux prefix: - Prefix: `/home/linuxbrew/.linuxbrew` - Keep the install/build logic in the Dockerfile, before `USER coder`. - Make the resulting prefix writable by `coder` before switching users. Prefer the smallest-diff approach that leaves `brew install ...` usable as `coder`. 4. Install `mise` to a stable image-owned path instead of relying on `~/.local/bin`: - Preferred binary path: `/usr/local/bin/mise` - Use a pinned installation method that fits the current Dockerfile style (versioned release asset or otherwise explicitly pinned installer path). 5. Add defensive build-time sanity checks near the install steps so the image fails early if assumptions are wrong: - `test -x /usr/local/bin/mise` - `test -x /home/linuxbrew/.linuxbrew/bin/brew` - `brew --version` - `mise --version` **Quality gate:** both Dockerfiles build locally, and the resulting container can run `brew --version` and `mise --version` as `coder`. ### Phase 2 — Make `mise` win PATH resolution by default 1. After `USER coder` in both Dockerfiles, define stable environment variables for the final shell/runtime behavior: - `HOMEBREW_PREFIX=/home/linuxbrew/.linuxbrew` - `MISE_DATA_DIR=/home/coder/.local/share/mise` - `MISE_ACTIVATE_AGGRESSIVE=1` only if later shell activation proves necessary 2. Replace the final PATH composition so it resolves in this order: 1. `mise` shims 2. Homebrew `bin`/`sbin` 3. Existing `/home/coder/go/bin` 4. Existing image/system PATH 3. Keep the current Go/Rust/Node setup intact aside from the final PATH ordering. Add a short Dockerfile comment explaining that `mise` shims must be first so `mise doctor` and `command -v` resolve `mise`-managed tools ahead of Homebrew/system binaries. 4. Do **not** rely on image-baked `mise` state under `/home/coder` for the initial implementation. The goal here is binary availability and path precedence, not preinstalling shared `mise` toolchains. **Quality gate:** in a fresh container as `coder`, `echo "$PATH"` shows `mise` shims before Homebrew, and `mise doctor`/`mise doctor path` show no PATH or activation problem in the tested shell entrypoints. ### Phase 3 — Add shell-init hardening only if smoke tests prove it is needed 1. Start with the Dockerfile `ENV PATH` solution as the default behavior. 2. If dogfooding shows that supported login shells still need shell integration beyond the final `ENV PATH`, add minimal global shell-init files under: - `dogfood/coder/ubuntu-22.04/files/etc/profile.d/` - `dogfood/coder/ubuntu-26.04/files/etc/profile.d/` 3. If these files are needed, keep them narrowly scoped: - a Homebrew file that exports/evals `brew shellenv` - a `mise` file that only reinforces the intended shims-first behavior 4. Avoid touching per-user dotfiles in `/home/coder`; they are the wrong place for required image behavior because of the persistent home volume. **Quality gate:** if profile.d files are added, login-shell smoke tests pass and we do not introduce new PATH-order regressions versus the Dockerfile-only path. ## Acceptance criteria - Both Ubuntu dogfood Dockerfiles are updated in one change and still build. - `brew` is installed in `/home/linuxbrew/.linuxbrew` and is usable as `coder`. - `mise` is installed at `/usr/local/bin/mise` and is usable as `coder`. - `mise doctor` does not report an activation/PATH-ordering problem in the shell entrypoints we verify. - Final PATH precedence is: 1. `mise` shims 2. Homebrew `bin`/`sbin` 3. existing user/tool paths 4. system paths - Existing dogfood workflows still work for Go/Rust/Node tooling after the PATH change. - The change passes the dogfood image CI path in `.github/workflows/dogfood.yaml`. ## Dogfooding and verification 1. Build both images locally: - `dogfood/coder/ubuntu-22.04` - `dogfood/coder/ubuntu-26.04` 2. Run each image with an empty mounted home volume at `/home/coder` to mimic the actual dogfood runtime constraint instead of only testing the image’s baked filesystem. 3. Capture a short terminal recording and screenshots for each variant showing: - `brew --prefix` - `brew --version` - `mise --version` - `echo "$PATH"` - `mise doctor` - `mise doctor path` 4. Verify at least one login-shell path and one non-login-shell path, so we can tell whether Dockerfile `ENV PATH` is sufficient or whether `/etc/profile.d` hardening is required. 5. Add one tool-resolution smoke test that proves `mise` wins when configured: - install/use a small `mise`-managed runtime as `coder` - run `which -a <tool>` - run `<tool> --version` 6. Verify existing image behavior did not regress: - `go version` - `node --version` - any other must-have image tools that were already on PATH 7. Preserve the artifacts from dogfooding for review: - screenshots attached to the change summary - a short screen recording (or terminal recording) covering the smoke test ## Risks and decision points - **Homebrew ownership model:** installing Homebrew during `docker build` is not enough by itself; the prefix must end up writable for `coder`. - **Scope control:** the initial change should solve `mise doctor` by fixing PATH precedence, not by introducing a larger `mise`-managed tool bootstrap. - **Shell-init uncertainty:** if the dogfood terminal entrypoints do not source `/etc/profile`, a Dockerfile `ENV PATH` fix may be sufficient and profile.d may be unnecessary. This should be decided by smoke tests, not by assumption. - **Persistent home behavior:** avoid any required implementation detail that only works if fresh volumes copy image-baked `/home/coder` contents. <details> <summary>Why this is the lowest-risk path</summary> This plan keeps the initial implementation focused on the user’s stated goal: install Homebrew and `mise`, then guarantee that `mise`-controlled paths win so `mise doctor` stays quiet. The main repo-specific constraint is the persistent `/home/coder` volume. That pushes required binaries and ownership-sensitive state out of `/home/coder` where possible, and it argues against relying on user dotfiles for required image behavior. Starting with Dockerfile-level install steps plus a final PATH reorder keeps the diff small, makes behavior consistent across shells, and gives us a clean place to add shell-init hardening only if the smoke tests prove it is necessary. </details> </details> --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `openai:gpt-5.5` • Thinking: `xhigh`_ |
||
|
|
2ff05608d2 |
test: stabilize chatdebug heartbeat threshold test (#25022)
`launchHeartbeat` could miss a stale-threshold update during startup if `SetStaleAfter` ran after the heartbeat ticker was created but before the goroutine subscribed to `thresholdChan`. In that case, the heartbeat kept the old interval until a future tick, and the mock-clock test could time out waiting for `Ticker.Reset` without advancing time. Subscribe to `thresholdChan` before reading the heartbeat interval so the channel consistently invalidates the interval. The regression test now changes the threshold while ticker creation is trapped, making the startup race deterministic. Closes https://github.com/coder/internal/issues/1513 |
||
|
|
100ebd9f3b |
test(coderd/x/chatd): deflake advisor chain mode snapshot (#25021)
`TestAdvisorChainMode_SnapshotKeepsFullHistory` was using the generic active chatd test server, which leaves periodic pending-chat polling enabled. That made the test inconsistent with the other OpenAI Responses API tests and allowed stale pending pubsub notifications to interrupt the second turn before the advisor request was observed. Use the existing OpenAI Responses test server helper so pending-chat acquisition is delayed and the test only starts processing after the SendMessage pending notification has been published. Closes https://github.com/coder/internal/issues/1510 |
||
|
|
ef0151601e |
feat: report insufficient quota build failures in chat tools (#24956)
## Summary When a workspace build fails because the user is over their group quota, the chat tools currently surface the failure as a bare `"workspace build failed: insufficient quota"` string with no machine-readable error code and no visibility into the user's current usage. Agents and the UI cannot distinguish quota failures from any other Terraform error, so users see an opaque message and have no clear path to recovery. This PR tags quota failures with a typed error code at the source and propagates it through the chat tool layer so callers can react to it explicitly. Relates to CODAGT-20 ## Changes **Provisioner runner** - Add `InsufficientQuotaErrorCode = "INSUFFICIENT_QUOTA"` and set it explicitly at the `commitQuota` failure site via a new `failedWorkspaceBuildfCode` helper, so `provisioner_jobs.error_code` is populated only on the genuine quota path. The substring matcher used for externally produced sentinels (e.g. `"missing parameter"`, `"required template variables"`) is intentionally not extended; provider errors that happen to mention "insufficient quota" stay classified as generic build failures. **SDK and API contract** - Add `JobErrorCodeInsufficientQuota` and a `JobIsInsufficientQuotaErrorCode` helper to `codersdk`. - Extend the swagger `enums` tag on `ProvisionerJob.ErrorCode` to include `INSUFFICIENT_QUOTA`. - Regenerate `coderd/apidoc`, `docs/reference/api/*`, and `site/src/api/typesGenerated.ts`. **chattool create_workspace / start_workspace** - `waitForBuild` now returns a typed `*workspaceBuildError` carrying both the message and the `JobErrorCode`, instead of a bare error string. - New `quotaerror.go` introduces a structured `quotaErrorResult` (with `error_code`, `title`, `message`, `build_id`, and optional `quota`) and a best-effort `workspaceQuotaDetails` lookup that wraps owner authorization internally and fetches `credits_consumed` and `budget` from the database. Quota lookup failures (including authorization failures) never block the failure payload. - On quota-coded build failures, both `create_workspace` and `start_workspace` now return the structured response (with the recovery guidance inlined into `message`) instead of the bare `"insufficient quota"` string. This applies to all three failure paths: post-creation, an in-progress existing build, and a freshly triggered start build. Non-quota build failures continue to use the existing `buildToolResponse` / `newBuildError` path. - Owner authorization is wrapped only on the call sites that need it (the `CreateFn` and `StartFn` invocations and the quota-detail lookup), so idempotent fast paths (already running, already in progress, existing-workspace early returns) do not pay for an extra RBAC round-trip or fail when role lookup is transient. ## Out of scope - No changes to quota math, allowances, or bypass behavior. - No automatic retries. - No new quota-inspection tools and no changes to MCP `coder_create_workspace` (which returns immediately and never observed the build outcome here). - No frontend UI changes; those will land in a follow-up PR that consumes the new `INSUFFICIENT_QUOTA` code. |
||
|
|
3c3708f562 |
test(codersdk/toolsdk): cover start without auto-bump (#24918)
Previously, the `CreateWorkspaceBuild` toolsdk tests only exercised a start where the workspace's prior template version was also the template's active version, so they did not prove that a plain start keeps using the previously built version. Replace that tautological coverage with an isolated fixture that advances the template's active version and asserts a start without `TemplateVersionID` still reuses the prior build's version. |
||
|
|
6737e2588e |
fix(site): reduce agents beta badge size from sm to xs (#25011)
Reduces the beta badge size in the Coder Agents UI from `sm` to `xs` for better visual balance with the logo. ## Changes - Added `xs` size variant to `FeatureStageBadge`, styled to match the existing `Badge` component's `xs` variant (`text-2xs`, `h-[18px]`, `border-0`, `rounded`) - Updated both usages in `AgentPageHeader` (mobile) and `AgentsSidebar` (desktop) from `size="sm"` to `size="xs"` - Added `ExtraSmallBeta` Storybook story for the new size > Generated by Coder Agents |
||
|
|
9d1315ffba | refactor(site): align user settings layout with organization settings (#25016) | ||
|
|
8c2b1c7d69 |
chore: de-emotion style constant (#24835)
This pull-request looks at all (most) of our instances of `const styles
= { ... }` and attempts to smooth them down into the minimum viable
Tailwind equivalent 🙂
|
||
|
|
d19e5f86a7 | fix(site): use ExternalImage on template insights (#25010) | ||
|
|
8ac4b9ab45 | refactor: remove unnecessary typeof window checks (#24999) | ||
|
|
f5ad6fb4cb | fix(site): improve info icon styles in audit and connection log rows (#25009) |