mirror of
https://github.com/coder/coder.git
synced 2026-11-11 03:21:02 +08:00
5b87d7b74fd19c19098a561222e5405eb33e2b9d
5148
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
eedde58b55 |
chore: bump protobufjs from 7.5.5 to 7.5.6 in /site (#25222)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 7.5.5 to 7.5.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/protobufjs/protobuf.js/releases">protobufjs's releases</a>.</em></p> <blockquote> <h2>protobufjs: v7.5.6</h2> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">7.5.6</a> (2026-04-27)</h2> <h3>Bug Fixes</h3> <ul> <li>Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454">75392ea</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/protobufjs/protobuf.js/blob/protobufjs-v7.5.6/CHANGELOG.md">protobufjs's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">7.5.6</a> (2026-04-27)</h2> <h3>Bug Fixes</h3> <ul> <li>Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454">75392ea</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.3...protobufjs-v7.5.4">7.5.4</a> (2025-08-15)</h2> <h3>Bug Fixes</h3> <ul> <li>invalid syntax in descriptor.proto (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2092">#2092</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/5a3769a465fead089a533ad55c21d069299df760">5a3769a</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.2...protobufjs-v7.5.3">7.5.3</a> (2025-05-28)</h2> <h3>Bug Fixes</h3> <ul> <li>descriptor extensions handling post-editions (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2075">#2075</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/6e255d4ad6982cc857f26e1731c2cedcf5796f68">6e255d4</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.1...protobufjs-v7.5.2">7.5.2</a> (2025-05-14)</h2> <h3>Bug Fixes</h3> <ul> <li>ensure that types are always resolved (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2068">#2068</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/4b51cb2b8450b77f9f5de1c562e7fae93b19d040">4b51cb2</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.0...protobufjs-v7.5.1">7.5.1</a> (2025-05-08)</h2> <h3>Bug Fixes</h3> <ul> <li>optimize regressions from editions implementations (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2066">#2066</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/6406d4c18afae309fc7b5f4a24d9674d85da180b">6406d4c</a>)</li> <li>reserved field inside group blocks fail parsing (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2058">#2058</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/56782bff0c4b5132806eb1a6bc4d08f930c4aaad">56782bf</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.4.0...protobufjs-v7.5.0">7.5.0</a> (2025-04-15)</h2> <h3>Features</h3> <ul> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/f04ded3a03a3ddd383f0228e2fe2627a51f31aa3">f04ded3</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/ac9a3b9fe3134d48187e41b08d54ffaceddc6c1b">ac9a3b9</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/e5ca5c84e326699e10258367883a54934e0bfe14">e5ca5c8</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/a84409b47f9ba0dba56da1af8054fb54f85d85a1">a84409b</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/9c5a178c4b59e0aa65ecac0bd7420171213b2ff9">9c5a178</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/b2c686721e3b63d092419fa1cbe58e1deb89534e">b2c6867</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/60f3e51087ca2c247473410f39331e1c766aefef">60f3e51</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/a6563617de04d510d6e8865eb6c5067f10247f64">a656361</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/869a95b1e5f553c76243aac45619061407a41084">869a95b</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/protobufjs/protobuf.js/commit/2189e5beeca6a70e4c104dfdb9fb8200bc5f81fe"><code>2189e5b</code></a> chore: release protobufjs-v7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2174">#2174</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454"><code>75392ea</code></a> fix: Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/8af8d7c0e9800879625f7d0d4a7fb51beb4410cd"><code>8af8d7c</code></a> chore(ci): Fix 7.x release please configuration (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2169">#2169</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/e92ca42244ad67203b48d836290062dae037ead6"><code>e92ca42</code></a> chore(ci): Enable release-please for 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2166">#2166</a>)</li> <li>See full diff in <a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">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 protobufjs since your current version.</p> </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> |
||
|
|
9810d299d2 |
chore: make dynamic parameters TemplateEmbedPage the default (#25069)
|
||
|
|
969da320ec |
feat: export Coder Agents debug logs (#25039)
Adds JSON export actions to the Coder Agents Debug panel so users can download either the current chat's recent debug runs or one expanded run for support sharing. The export reuses the existing chat debug endpoints and react-query cache, adds Storybook and unit coverage for the JSON envelope, and updates the chat debug logging docs with UI and cURL instructions. Refs CODAGT-280. Generated by Coder Agents. <details> <summary>Implementation notes</summary> - Chat-level export fetches full detail for each listed debug run with `queryClient.fetchQuery(chatDebugRun(chatId, run.id))` and writes a single JSON file. - Run-level export uses the already-loaded detail query data from an expanded run card. - The JSON envelope includes `version`, `scope`, `exported_at`, `chat_id`, and either `runs` or `run`. - The chat-level export reflects the current backend list endpoint behavior, up to the 100 newest debug runs. - Agent-browser dogfooding verified files were downloaded and that `jq` validated the chat-level and run-level JSON contents. </details> |
||
|
|
b5e1ea33d8 |
feat: add AI budget policy and period deployment config (#25122)
Closes https://linear.app/codercom/issue/AIGOV-283/add-deployment-config-for-ai-budget-policy-and-period Adds `CODER_AI_BUDGET_POLICY` and `CODER_AI_BUDGET_PERIOD` deployment options for AI Governance cost controls. |
||
|
|
fabf7d31fc |
test: use default provider in TestPatchChatMessage/ChangesModel (#25189)
`TestPatchChatMessage/ChangesModel` hardcoded `"openai"` as the provider for the override model config. After #25171, the shared chat test harness registers a single `"openai-compat"` provider by default, so calling `createAdditionalChatModelConfig(..., "openai", ...)` fails with HTTP 400 `Chat provider is not configured` before the test can exercise the model-change path. The subtest was added in #25084 after #25171 was reviewed, so the harness change and the new hardcoded provider only met on `main`. Use `defaultModel.Provider` so the override always matches whatever provider the harness registered. This mirrors every other call site of `createAdditionalChatModelConfig` in the file. Closes https://github.com/coder/internal/issues/1530 |
||
|
|
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. |
||
|
|
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. 🧑💻 |
||
|
|
b0b07536fc | feat: add opt-in Coder identity headers for MCP servers (#25153) | ||
|
|
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>
|
||
|
|
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. |
||
|
|
a55430b8fd | fix(site/src/pages/AgentsPage): suppress last-message spacer during active stream (#25120) | ||
|
|
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 |
||
|
|
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>
|
||
|
|
592e45dcfb |
chore: bump coder-guts dependency (#25154)
Bump coder/guts to v1.7.0. Related PR: https://github.com/coder/guts/pull/81 |
||
|
|
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.
|
||
|
|
81561454d6 |
revert: "fix(site): enlarge checkbox click target in workspace and task tables" (#25159)
Reverts coder/coder#24739 |
||
|
|
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> |
||
|
|
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. |
||
|
|
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. |
||
|
|
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. |
||
|
|
a1dbd758bc | feat: add template builder deployment config and telemetry types (#25082) | ||
|
|
febabfb8b2 |
feat: add request/response dump support to aibridgeproxyd (#24837)
Closes https://github.com/coder/coder/issues/24335 |
||
|
|
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) | ||
|
|
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 |
||
|
|
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 |
||
|
|
400374992c | fix: add pnpm overrides for vulnerable transitive dependencies (#25064) | ||
|
|
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> |
||
|
|
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> |
||
|
|
be5753dd63 | chore: pin overrides in site/package.json (#25052) | ||
|
|
9fd2cc78fe | refactor(site): migrate more styles from emotion to tailwind (#24914) | ||
|
|
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> |
||
|
|
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 |
||
|
|
273e828442 | fix: remove advisor reasoning configuration (#25030) | ||
|
|
20453e123e | fix(site): clamp lander position on landing to keep feet on pad (#25026) | ||
|
|
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> |
||
|
|
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. |
||
|
|
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) | ||
|
|
4e1dccaabd |
refactor: remove ChooseOne component (#24983)
|
||
|
|
894a1e0f7f | feat(site): add Codernauts lunar lander game (#25001) | ||
|
|
92b1fc48b4 | fix(site/src/pages/AgentsPage/components): right-align user chat bubbles (#25000) |