mirror of
https://github.com/coder/coder.git
synced 2026-10-31 02:43:21 +08:00
d5a3963167cc31396ebcbf7ddc8e894371a9cf44
5611
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d5a3963167 |
feat: add bulk user secret import endpoint and SDK client (PLAT-240) (#26724)
Adds `POST /api/v2/users/{user}/secrets/batch` and
`codersdk.Client.ImportUserSecrets` to import env, JSON, or YAML secrets
atomically. The endpoint validates each entry, rolls back the full batch
on conflicts or limits, omits secret values from responses and audit
logs, and imports keys that cannot be injected as environment variables
with an empty `env_name`.
Part of the [PLAT-240 bulk secret import
stack](https://linear.app/codercom/issue/PLAT-240). Reviewed and updated
by Coder Agents on behalf of @dylanhuff-at-coder.
|
||
|
|
10624122c5 |
feat(site/src): show spend for unlimited and zero AI budgets (#27458)
The group members table hid a member's spend behind a bare "Unlimited"
label when their budget resolves to a group with no limit, and rendered
a $0 budget as a special "None" label. Spend now always shows: as
"$X / Unlimited USD" for unlimited budgets, and as a normal limit row
("Group limit $0", exceeded color once spend is above zero) for $0
budgets.
The Everyone badge drops "(not allocated)" when the Everyone group's
own budget or a user override applies, showing "Everyone" or
"Everyone (individual)" instead. The not-attributed tooltip now states
that the amount is the user's spend in the viewed group and that their
AI budget is managed by another group, replacing the misleading
"Not attributed to this group" wording.
|
||
|
|
3c7a1d33e3 |
feat: add persisted whole-chat summary with background generation (#26657)
Adds a persisted whole-chat summary that backs the chat summary popover. A new nullable `chats.summary` column is populated in the background after a successful root-chat turn and pushed to clients via a new `chat_summary_change` watch event (distinct from `summary_change`, which is bound to `last_turn_summary`), so the popover reads `chat.summary` straight off the loaded `Chat` with no extra query. This is the data source for the popover and per-chat cost UI built in #26649; the popover can consume `chat.summary` once this lands (the field is nullable, so merge order does not matter). ## How it works - **Generation** runs in the existing successful-turn finalize hook, detached from the request so the user's turn is never blocked. A cadence gate generates the first summary after one completed turn, then regenerates every three turns, using the `chats.summary_generated_at` freshness marker. Generation reads compaction-aware history, renders it to a bounded plain-text transcript (short transcripts are skipped), and asks for a 1-3 sentence summary via structured output. Failures never clear an existing summary. - **Staleness** is guarded by `history_version` (mirroring `last_turn_summary`), so a background write racing a newer turn loses while worker lifecycle transitions cannot reject a fresh write. - **Model selection** uses the chat's configured model. ## Deferred to follow-ups - **Cost accounting**: the `chat_messages.cost_source` discriminator and summary/title usage recording were removed from this PR so summary persistence is not blocked by hidden accounting rows advancing `history_version`. Title usage recording stays on main's `InsertChatMessages` path. - **Model override**: deployment-wide summary generation model selection is split into #26803; the base feature always uses the chat model. ## Notes - Migration `000540` adds `chats.summary` and `chats.summary_generated_at`, and recreates `chats_expanded` to expose the new columns. - Root chats only; shared viewers pick up the summary on their next refetch (live watch events are owner-only). Refs #26649 --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
9ce366414e | fix(site): remember reasoning effort per model on new chat (#27457) | ||
|
|
c23f2c0223 |
feat: fall back to the Everyone group for AI spend attribution (#27364)
## Description Previously, a user with no per-user override and no membership in a budgeted group had no effective group, so their AI spend was attributed nowhere and was, therefore, untracked. This change falls back to the organization's Everyone group when no override or group budget applies. Since every user in an organization is implicitly a member of that org's Everyone group, spend is now attributed and tracked for any user with organization membership. A user with no organization membership resolves to no group, so their daily spend is not incremented and a warning is logged. The fallback is unlimited, so enforcement is unaffected: only override and group budgets can block requests. For users in multiple organizations, an existing budget on any Everyone group is still chosen by the "highest" policy; when none is budgeted, the fallback prefers the default org, then orders by organization name. ## Changes - Add `ResolveUserEffectiveGroup` and the `GetUserEveryoneFallbackGroup` query: resolve override → group budget → Everyone group fallback. - Attribute token-usage spend and the user AI spend endpoint via the fallback, so unbudgeted users resolve to their Everyone group instead of null. - Update `GetGroupMembersAISpend` to surface the Everyone fallback as the effective group. - Update `GetHighestGroupAIBudgetByUser` to break ties by organization name then group name, keeping multi-org resolution deterministic and consistent with the fallback. - For multi-org users with no budget anywhere, the fallback picks the Everyone group deterministically: prefer the default org, then order by organization name. Closes https://linear.app/codercom/issue/AIGOV-509/fall-back-to-the-everyone-group-for-spend-attribution > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
52a687902f |
docs: add frontend-review skill for pre-PR FE rule audits (#27408)
## What Adds `.claude/skills/frontend-review`, a diff-scoped self-review skill that audits changes under `site/src/` against the FE1 to FE10 rule contract before a PR is created or updated. Each rule has a concrete "what to look for in a diff" checklist, and the output format is a terse per-rule PASS/FAIL table with `file:line` findings. Wiring: - `site/AGENTS.md` Pre-PR Checklist gains step 6: run the audit when the diff touches `site/src/`. - `.claude/skills/code-review` now cites FE rule IDs for frontend findings. - The deep-review `frontend-reviewer` role audits against the same contract. ## Why Most frontend review findings are semantic (missing interaction coverage, clobbered form state, near-duplicate components) and cannot be linted. Today they are caught post-hoc by reviewers and the review bot, which is exactly the "PRs get complaints" experience. Running the same rubric before the PR exists converts review rounds into pre-push fixes. Stacked on #27407 (the rule contract). The deterministic-checks follow-up (#27409) was closed; that subset will be enforced through proper linting instead. > This PR was written by Mux, an AI coding agent, on behalf of Mike. |
||
|
|
5565fcd03b |
docs: add frontend pattern rule contract (FE1-FE10) (#27407)
## What
Adds `.claude/docs/FRONTEND_PATTERNS.md`, a canonical frontend rule
contract for `site/src/` with ten stable rule IDs (FE1 to FE10), each
with short incorrect/correct examples using real repo idioms. Adds a
compact non-negotiables index at the top of `site/AGENTS.md` and links
the contract from the root `AGENTS.md` frontend routing line.
## Why
Frontend PRs keep drawing the same review findings. Mining the last 18
months of `site/` PR review data (330 closed/merged PRs, 1,105 inline
comments, 358 actionable pattern findings across 57 PRs) shows the
recurring themes, in order of frequency: missing Storybook interaction
coverage, loose TypeScript, component duplication and PR scope,
redundant comments, unhandled UI states, accessibility, react-query
misuse, and effect misuse. The guidance largely existed in
`site/AGENTS.md` already, but as unprioritized prose with no shared
vocabulary.
Stable rule IDs give reviewers, agents, and tooling one shared language
("FE7: re-typed query key"), and the rules are ordered by how often
reviewers actually flagged them.
This is the first PR of a stack of two:
1. This PR: the rule contract.
2. A `frontend-review` skill that audits diffs against these rules
pre-PR (#27408).
A third PR with a deterministic ratchet script (#27409) was closed; the
machine-checkable subset will be enforced through proper linting
instead.
## Notes for reviewers
The rule content is derived from your own review comments (for example,
the re-typed query key example in FE7 mirrors feedback on #27385). If a
rule does not match how you want the frontend built, the contract file
is the place to change it.
> This PR was written by Mux, an AI coding agent, on behalf of Mike.
|
||
|
|
1c2bb07b81 | chore(site): upgrade to pixel 0.2 (#27353) | ||
|
|
6b22383823 |
fix(site/src/pages/TemplateBuilder): show all step content without inner scroll (#27437)
## Summary The Template Builder steps clipped their content to an inner scrollbar via `max-h-[calc(...)]` + `overflow-y-auto`, so the base picker showed fewer than three rows before requiring scroll. This removes those wrappers from all four steps so every base/module renders and the page scrolls naturally. Resolves DEVEX-585. ## Changes - `BaseInfraSelectStep.tsx` — base picker grid (3-col grid retained) - `ModuleSelectStep.tsx` — module picker grid - `ModuleSettingsStep.tsx` — module variables list - `BaseTemplateParametersStep.tsx` — base config; unwrapped the now-styleless wrapper `div` into the fragment The sticky sidebar summary (`SelectionSummary.tsx`) is intentionally left as-is; it is not a wizard step. ### Tradeoff With the inner scroll removed, the Back/Continue controls sit below the full grid, so reaching them requires page scroll when a list is long. This matches the requested "just show all of em" behavior. https://github.com/user-attachments/assets/7e371850-7b97-42c7-b92c-5ac00a3e7979 <details> <summary>Implementation plan</summary> # DEVEX-585: Show more base templates before requiring scroll ## Problem The base template picker on the Template Builder feels too narrow: it clips to fewer than three rows before an inner scrollbar appears. ## Root cause The step grids were wrapped in `max-h-[calc(100vh-420px)] overflow-y-auto` (and `340px` variants), constraining height so only a couple of rows showed before an inner scrollbar clipped the rest. ## Approach (chosen: remove inner scroll) Show all content and let the page scroll naturally by removing the height/scroll utilities (and stale comments) from each step's container. Applied to the base picker, base parameters, module picker, and module settings steps. ## Testing / verification - Biome check passes on all edited files; LSP reports no diagnostics. - Visual: each step renders all content with no inner scrollbar; the page scrolls if the list is long. ## Out of scope - The sidebar summary scroll (`SelectionSummary.tsx`) is not a wizard step. - Auto-filling customization fields (separate work, PR #27272). </details> --- This PR was generated by Coder Agents on behalf of @jeremyruppel. |
||
|
|
c309f4d5ff |
feat(site/src/pages/TemplateBuilder): auto-fill customization fields from base template (#27272)
Closes [DEVEX-586](https://linear.app/codercom/issue/DEVEX-586/auto-fill-customization-fields-from-selected-base-template). The Template Builder wizard's final **Customizations** step rendered empty inputs for ID, Display name, Description, and Icon. This seeds those fields with sensible defaults derived from the selected base template, while keeping every field editable. ## Changes All frontend, in `site/src/pages/TemplateBuilder/wizardState.ts`: - `SelectedBaseMeta` now carries `description`, mapped in `toSelectedBaseMeta`. - New pure helper `baseCustomizationDefaults(base)` maps the base to `{ name: base.id, displayName: base.name, description, icon }`. - `SET_BASE` seeds the four customization fields when the base changes (still clearing base variable values). Re-selecting the same base preserves user edits. - `initWizardState` seeds the same defaults for the `?base=` deeplink entry path. - `RESET_CUSTOMIZATIONS` (fired on back-navigation) now resets only organization/provisioner state, so auto-filled values survive stepping back and forth. No change was needed in `TemplateCustomizationsStep.tsx`; it already binds to these state fields, so seeded values render and stay editable. Existing placeholders remain as the fallback when a base value is empty (e.g. `scratch`). ### Default mapping | Form field | State key | Source | | ------------ | ------------- | ------------------ | | ID | `name` | `base.id` | | Display name | `displayName` | `base.name` | | Description | `description` | `base.description` | | Icon | `icon` | `base.icon` | `base.id` is used for the ID field because base ids are already valid template slugs (`docker`, `aws-linux`, ...). Icon values are already served asset paths (`/icon/*`, `/emojis/*`), so no lookup map is needed. ## Testing - `wizardState.test.ts`: 27 passing, including new coverage for seeding, base-change re-seed, same-base edit preservation, `RESET_CUSTOMIZATIONS`, `initWizardState`, `toSelectedBaseMeta`, and `baseCustomizationDefaults`. - `biome check` clean; `tsc --noEmit` clean. <img width="1043" height="593" alt="Screenshot 2026-07-15 at 2 17 19 PM" src="https://github.com/user-attachments/assets/25620df4-b020-4430-b5f3-9ce8b7b9f379" /> <details> <summary>Implementation plan</summary> # DEVEX-586: Auto-fill customization fields from selected base template ## Goal In the Template Builder wizard, the final **Customizations** step currently renders empty inputs for Display name, Description, ID, and Icon. Pre-populate these with sensible defaults derived from the selected base template, while keeping every field editable. Organization is already auto-selected when a single org is available, so it is out of scope beyond leaving it untouched. Source: Linear DEVEX-586 (Ben Potter): "Would love if all these options ... were auto-filled and generated and can be edited versus the user manually filling it out." Fields called out: display name, description, ID, and icon. ## Current behavior (findings) Frontend lives in `site/src/pages/TemplateBuilder/`. - `TemplateCustomizationsStep.tsx` renders the four fields bound to `state.displayName`, `state.description`, `state.name` (the "ID" field), and `state.icon`. All start empty (`initialWizardState`). - `wizardState.ts` holds the state, the `wizardReducer`, and the `SelectedBaseMeta` UI type. - `SelectedBaseMeta` did not carry `description`. - `toSelectedBaseMeta(base)` maps the API `TemplateBuilderBase` into `SelectedBaseMeta`. - `SET_BASE` set the base and cleared `baseVariableValues` only when the base id changed; customization fields were left empty. - `RESET_CUSTOMIZATIONS` (dispatched by `handleBack`) blanked org/provisioner plus `name`, `displayName`, `description`, `icon`. - `initWizardState(preselectedBase)` seeded `baseTemplateId` and `selectedBase` for deeplinks but left customization fields empty. - API type `TemplateBuilderBase` exposes `id`, `name`, `description`, `icon`, `os`, `variables`, `prerequisites`. - Backend (`coderd/templatebuilder_handler.go`) builds each base from the built-in `TemplateExample`: `id = ex.ID`, `name = ex.Name`, `description = ex.Description`, `icon = ex.Icon`. - Base IDs are valid template names (lowercase, hyphen-separated): `docker`, `kubernetes`, `aws-linux`, `aws-windows`, `gcp-linux`, `gcp-windows`, `azure-linux`, `digitalocean-linux`, `scratch`. ## Default mapping | Form field | State key | Default source | | --- | --- | --- | | ID (required) | `name` | `base.id` | | Display name | `displayName` | `base.name` | | Description | `description` | `base.description` | | Icon | `icon` | `base.iconUrl` (`base.icon`) | | Organization | `organizationId` | unchanged (already auto-selected) | Rationale for `name = base.id`: base ids are guaranteed valid template slugs, whereas slugifying the human display name is lossy and can collide. The field stays editable. ## Icon default: confirmed, no map needed The API already returns normalized, served asset paths in `base.icon` (e.g. `/icon/docker.png`, `/icon/aws.svg`, `/emojis/1f4e6.png` for `scratch`), the same values `CreateTemplatePage` assigns when creating from a built-in example. `IconField` accepts any URL/path, so every base renders correctly. A base-id-to-icon map is unnecessary. ## Implementation Frontend-only, in `wizardState.ts`: 1. Add `description?: string` to `SelectedBaseMeta`; map it in `toSelectedBaseMeta`. 2. Add pure helper `baseCustomizationDefaults(base)` returning `{ name, displayName, description, icon }`. 3. `SET_BASE`: on base change, spread the defaults alongside the `baseVariableValues: {}` reset; on same-base re-selection, preserve existing values. 4. `initWizardState(preselectedBase)`: spread defaults into the returned state. 5. Narrow `RESET_CUSTOMIZATIONS` to reset only `organizationId` and `hasProvisioners`. 6. `toCreateTemplateRequest` already sends the fields, so no payload change. ## Tests Reducer unit tests in `wizardState.test.ts` for seeding, base-change re-seed, same-base edit preservation, `RESET_CUSTOMIZATIONS`, `initWizardState`, `toSelectedBaseMeta` (description carried), and `baseCustomizationDefaults`. ## Scope / non-goals - No backend changes; the API already returns all needed fields. - Organization auto-selection is unchanged. - No slug transformation of display names (base id is used directly). - No base-id-to-icon map. </details> --- *Opened by Coder Agents on behalf of @jeremyruppel.* |
||
|
|
02fd1cc691 | feat: allow spawn_agent model and reasoning effort override (#27385) | ||
|
|
99e740bdb7 |
feat: add user secrets file parser and shared validator (PLAT-240) (#26723)
Part of the **PLAT-240** bulk secret import stack: this PR adds the `codersdk` parser and shared create-secret validator used by the follow-up batch endpoint and UI PRs. `ParseSecretsFile` parses `.env`, `.json`, and `.yaml` files into `CreateUserSecretRequest` entries in source order, with size, count, duplicate-key, structure, and malformed-input checks. `ValidateCreateUserSecretRequest` now backs the single-create handler too, so create validation has one SDK-level implementation. Part of https://linear.app/codercom/issue/PLAT-240 > This PR was generated by Coder Agents on behalf of @dylanhuff-at-coder. |
||
|
|
ff71bb3850 | fix(site): align AI Settings model provider dropdowns (#27391) | ||
|
|
f17d488479 |
feat: add network call badges to AI sessions table (#27341)
Surface the total and blocked Agent Firewall network calls on the AI sessions list. Sessions that did not pass through Agent Firewall show as "Disabled". <img width="2842" height="1366" alt="image" src="https://github.com/user-attachments/assets/2a68b4a9-4d93-454d-a06e-5f0d0b734a33" /> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
507ce504f8 | refactor(site): align AgentsPage layout naming with codebase conventions (#27378) | ||
|
|
6ec45f75c6 |
chore(site): replace handrolled AI spend types with generated types (#27342)
The groups and group members pages consumed AI spend through local ai_cost_control wrapper types with TODOs to adopt the generated contract. Both spend endpoints are now live, so this switches to the generated types and hardens the fetch path. - Use OrganizationGroupsAISpend and GroupMembersAISpend from typesGenerated for the org groups and group members spend endpoints - Fetch identity and spend separately, joining by group_id/user_id at the container so each row gets one enriched object - Batch spend requests at the backend cap of 100 IDs in the API client and merge the responses, with table-driven tests covering both endpoints - Treat a null effective_group_id as a budget managed by a group in another org: render an em-dash with an info tooltip and skip the group name lookup instead of firing an empty-ID request Closes AIGOV-509 |
||
|
|
608c2ee46f |
fix(site/src/pages/AgentsPage/components/ChatMessageInput): scroll skills menu selection into view (#27345)
When navigating the slash skills menu with arrow keys, moving the highlight past the visible area did not scroll the list, so the selected skill went out of view. The menu drives cmdk in controlled mode while arrow keys are consumed by the Lexical trigger plugin, so cmdk's internal scroll-into-view never runs for keyboard navigation. This adds a layout effect in `SkillsTriggerMenu` that scrolls the highlighted item (and its group heading when it is the first item in a group) into view on keyboard-driven index changes, while skipping pointer-driven highlights to avoid hover/scroll loops, matching cmdk's own behavior. Covered by two new interaction stories that fail without the fix: `ScrollsSelectionIntoView` (menu in isolation) and `ArrowKeysScrollMenuList` (end-to-end arrow-key wrap in `ChatMessageInput`). > Opened by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
dcf3cce51c |
fix(site/src/pages/AgentsPage): clarify empty context usage popover state (#27389)
## Summary The context usage badge popover showed "Context usage unavailable" before any assistant message reported token usage, which read like an error. This changes the empty-state copy to "Context usage will appear after sending a message." and fixes a spacing bug that state exposed: the pinned context list's top margin was conditional on a usage percentage being present, so without usage data the list sat flush against the message. ## Changes - `ContextUsageIndicator`: new empty-state copy; unconditional `mt-2` on the context list. - Stories: `NoUsage` (message only) and `NoUsageWithContext` (message plus pinned resource list), both asserting the new copy via hover interactions. ## Testing - Storybook interaction stories cover both empty states. - `biome check` and `tsc --noEmit` pass; verified visually in Storybook. > This PR was authored by Mux, an AI coding agent, acting on Mike's behalf. |
||
|
|
a9a1dcc65d |
feat: add network calls column to AI sessions table (#27269)
Add a "Total/blocked network calls" column to the AIBridge sessions table. Update `ListAIBridgeSessions` query to calculate network called made and blocked per session. See query plan [here](https://explain.dalibo.com/plan/54355c90b165ggb4). --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6014a44c85 | fix(site): keep mobile model picker effort row and last model visible (#27336) | ||
|
|
3227cac217 |
feat: add manual chat compaction via /compact (#27081)
Adds a user-triggered `/compact` action for Coder Agents chats: typing
`/compact` in the composer (or picking it from the `/` trigger menu)
summarizes the conversation so far to free up context window space.
## How it works
- New `POST /api/experimental/chats/{chat}/compact` endpoint
(owner-only, RBAC `ActionUpdate`, excluded from the public API reference
via `x-apidocgen skip`). It marks the chat with a durable one-shot
`chats.compaction_requested_at` signal and moves it `waiting -> running`
via a new `RequestCompaction` state transition; no message row is
inserted. AI Gateway attribution needs no per-request key: generation
preparation resolves the owner's synthetic API key (#27170) like any
other turn.
- `RequestCompaction` hands off chat ownership (clears
`worker_id`/`runner_id`) so a worker acquisition hint is published;
since the transition changes no history, the previous runner could
otherwise miss the request under reordered pubsub delivery.
- The background chat worker picks the chat up like any other turn. A
pending manual request takes precedence over turn completion in the
generation decision, and forces compaction even below the automatic
threshold (and when compaction is disabled via threshold=100). The
commit step consumes the request marker in the same transaction; any
transition that ends the turn clears stale markers.
- The summary triplet reuses the automatic-compaction path, now tagged
with a `source` (`automatic` | `manual`) that is plumbed through
streamed progress parts, persisted tool JSON, and the UI label
("Summarized (manual)").
- Validation order: busy chats reject with 409 (state-machine conflict),
empty/already-compacted chats with 409 "nothing to compact", archived
chats with 400; the owner usage-limit check runs last so no-op requests
surface the specific conflict instead of a limit error.
- Web UI: the `/` trigger menu now has a built-in "Commands" group
listing `/compact`; submit intercepts exactly `/compact` and calls the
endpoint instead of sending a message. A personal or workspace skill
named `compact` takes precedence over the built-in command; while skill
collisions are still resolving, an exact `/compact` submission is
blocked with a retryable hint instead of leaking as message text.
History and queued-message edits are never intercepted. After
compaction, the context usage indicator resets to its unknown state
until the next assistant response reports fresh usage, instead of
showing the stale pre-compaction number.
- codersdk: `ExperimentalClient.CompactChat`.
Worker-path execution (rather than compacting synchronously in the
handler) reuses the existing lock fencing, live "Summarizing..."
streaming, retry accounting, restart resilience, and debug-run
observability. Rationale documented in `coderd/x/chatd/ARCHITECTURE.md`.
## Testing
- State machine: transition-matrix coverage for `RequestCompaction`,
marker lifecycle tests (carried by lease renewals/queue appends, cleared
by terminal transitions, consumed by commit), ownership handoff +
acquisition hint assertions.
- Worker: decision-ordering and forced-compaction unit tests;
active-server end-to-end test (manual compact below threshold produces a
`source=manual` summary, returns to `waiting`, no assistant follow-up;
busy chat rejected).
- API: success, archived, non-owner, RBAC-denied, empty-chat, no-daemon
cases; usage-limit ordering (at-limit owners still get
state/nothing-to-compact conflicts for no-op requests, with marker
rollback).
- Frontend: Storybook play tests for the Commands menu group, submit
intercept, skill-name collision, queued-edit passthrough, and
manual/automatic tool rendering; unit tests for command availability
resolution and the post-compaction context usage reset.
> This PR was created by Mux, an AI coding agent, working on Mike's
behalf.
|
||
|
|
69a045f944 |
chore: bump axios from 1.16.1 to 1.18.0 in /site (#27350)
Bumps [axios](https://github.com/axios/axios) from 1.16.1 to 1.18.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/releases">axios's releases</a>.</em></p> <blockquote> <h2>v1.18.0 — June 13, 2026</h2> <p>This release hardens redirect and URL handling, improves the validateStatus configuration semantics, and includes updates to documentation, dependencies, and release metadata.</p> <h2>🔒 Security Fixes</h2> <ul> <li> <p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter support for stripping caller-specified sensitive headers on cross-origin redirects, helping prevent custom auth headers such as API keys from leaking to another origin. (<strong><a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p> </li> <li> <p><strong>URL And Request Hardening:</strong> Rejects malformed <code>http:</code> and <code>https:</code> URLs that omit <code>//</code> with <code>ERR_INVALID_URL</code>, while tightening prototype-pollution-safe config reads, stream size limits, FormData depth handling, data URL sizing, and local <code>NO_PROXY</code> matching. (<strong><a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p> </li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Status Validation:</strong> Added <code>transitional.validateStatusUndefinedResolves</code> so applications can opt in to treating <code>validateStatus: undefined</code> like the option was omitted, while <code>validateStatus: null</code> remains the explicit way to accept every status. (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li> <p><strong>Documentation:</strong> Published the v1.17.0 release notes, fixed a changelog typo, clarified the package update PR policy, and marked the <code>proxy</code> request config as Node.js-only in the advanced docs. (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p> </li> <li> <p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>, <code>@babel/preset-env</code>, <code>@commitlint/cli</code>, <code>@commitlint/config-conventional</code>, <code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>, <code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>, <code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>, <code>vitest</code>, and <code>actions/checkout</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p> </li> <li> <p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by updating package metadata and the runtime <code>VERSION</code> value. (<strong><a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p> </li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve axios:</p> <ul> <li><strong><a href="https://github.com/drori12"><code>@drori12</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li> <li><strong><a href="https://github.com/eyupcanakman"><code>@eyupcanakman</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> <li><strong><a href="https://github.com/Adi-Beker"><code>@Adi-Beker</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li> </ul> <p><a href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full Changelog</a></p> <h2>v1.17.0 — June 1, 2026</h2> <p>This release adds Node HTTP zstd decompression, hardens config and release workflows, and fixes authentication, header, proxy, and type-handling regressions.</p> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>, <code>params</code>, and <code>paramsSerializer</code> reads with own-property checks to prevent inherited prototype values from affecting request behavior, including SSRF-sensitive paths. (<strong><a href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li> <li><strong>Release Publishing:</strong> Switched the publish workflow to npm staged publishing for safer, auditable package releases with provenance. (<strong><a href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>HTTP Compression:</strong> Added Node HTTP adapter support for zstd response decompression, with <code>transitional.advertiseZstdAcceptEncoding</code> controlling whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Authentication Handling:</strong> Restored Basic auth on same-origin Node redirects while continuing to strip credentials cross-origin, and aligned the fetch adapter with HTTP adapter behavior for URL-embedded Basic auth. (<strong><a href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li> <li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code> TLS options when tunneling HTTPS requests through HTTP CONNECT proxies. (<strong><a href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li> <li><strong>React Native FormData:</strong> Cleared default <code>Content-Type</code> for React Native <code>FormData</code> so multipart boundaries can be generated correctly. (<strong><a href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's changelog</a>.</em></p> <blockquote> <h2>v1.18.0 — June 13, 2026</h2> <p>This release hardens redirect and URL handling, improves the validateStatus configuration semantics, and includes updates to documentation, dependencies, and release metadata.</p> <h2>🔒 Security Fixes</h2> <ul> <li> <p><strong>Redirect Header Safety:</strong> Added Node HTTP adapter support for stripping caller-specified sensitive headers on cross-origin redirects, helping prevent custom auth headers such as API keys from leaking to another origin. (<strong><a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a></strong>)</p> </li> <li> <p><strong>URL And Request Hardening:</strong> Rejects malformed <code>http:</code> and <code>https:</code> URLs that omit <code>//</code> with <code>ERR_INVALID_URL</code>, while tightening prototype-pollution-safe config reads, stream size limits, FormData depth handling, data URL sizing, and local <code>NO_PROXY</code> matching. (<strong><a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a></strong>)</p> </li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Status Validation:</strong> Added <code>transitional.validateStatusUndefinedResolves</code> so applications can opt in to treating <code>validateStatus: undefined</code> like the option was omitted, while <code>validateStatus: null</code> remains the explicit way to accept every status. (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li> <p><strong>Documentation:</strong> Published the v1.17.0 release notes, fixed a changelog typo, clarified the package update PR policy, and marked the <code>proxy</code> request config as Node.js-only in the advanced docs. (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</p> </li> <li> <p><strong>Dependencies:</strong> Bumped <code>@babel/core</code>, <code>@babel/preset-env</code>, <code>@commitlint/cli</code>, <code>@commitlint/config-conventional</code>, <code>@rollup/plugin-babel</code>, <code>@rollup/plugin-commonjs</code>, <code>@vitest/browser</code>, <code>@vitest/browser-playwright</code>, <code>eslint</code>, <code>lint-staged</code>, <code>rollup</code>, <code>vitest</code>, and <code>actions/checkout</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10996">#10996</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10997">#10997</a></strong>)</p> </li> <li> <p><strong>Release Metadata:</strong> Prepared the 1.18.0 release by updating package metadata and the runtime <code>VERSION</code> value. (<strong><a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a></strong>)</p> </li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve axios:</p> <ul> <li><strong><a href="https://github.com/drori12"><code>@drori12</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10984">#10984</a></strong>)</li> <li><strong><a href="https://github.com/eyupcanakman"><code>@eyupcanakman</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a></strong>)</li> <li><strong><a href="https://github.com/Adi-Beker"><code>@Adi-Beker</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a></strong>)</li> </ul> <p><a href="https://github.com/axios/axios/compare/v1.17.0...v1.18.0">Full Changelog</a></p> <h2>v1.17.0 — June 1, 2026</h2> <p>This release adds Node HTTP zstd decompression, hardens config and release workflows, and fixes authentication, header, proxy, and type-handling regressions.</p> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Config Hardening:</strong> Guarded <code>socketPath</code>, <code>params</code>, and <code>paramsSerializer</code> reads with own-property checks to prevent inherited prototype values from affecting request behavior, including SSRF-sensitive paths. (<strong><a href="https://redirect.github.com/axios/axios/issues/10901">#10901</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10922">#10922</a></strong>)</li> <li><strong>Release Publishing:</strong> Switched the publish workflow to npm staged publishing for safer, auditable package releases with provenance. (<strong><a href="https://redirect.github.com/axios/axios/issues/10926">#10926</a></strong>)</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>HTTP Compression:</strong> Added Node HTTP adapter support for zstd response decompression, with <code>transitional.advertiseZstdAcceptEncoding</code> controlling whether <code>zstd</code> is advertised in <code>Accept-Encoding</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/6792">#6792</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10920">#10920</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Authentication Handling:</strong> Restored Basic auth on same-origin Node redirects while continuing to strip credentials cross-origin, and aligned the fetch adapter with HTTP adapter behavior for URL-embedded Basic auth. (<strong><a href="https://redirect.github.com/axios/axios/issues/10929">#10929</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10896">#10896</a></strong>)</li> <li><strong>Proxy TLS:</strong> Preserved user <code>httpsAgent</code> TLS options when tunneling HTTPS requests through HTTP CONNECT proxies. (<strong><a href="https://redirect.github.com/axios/axios/issues/10957">#10957</a></strong>)</li> <li><strong>React Native FormData:</strong> Cleared default <code>Content-Type</code> for React Native <code>FormData</code> so multipart boundaries can be generated correctly. (<strong><a href="https://redirect.github.com/axios/axios/issues/10898">#10898</a></strong>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/axios/axios/commit/2d06f96e8602c2db13b65a26340ee4a1bbc0b61f"><code>2d06f96</code></a> chore(release): prepare release 1.18.0 (<a href="https://redirect.github.com/axios/axios/issues/11003">#11003</a>)</li> <li><a href="https://github.com/axios/axios/commit/32fc489632377d214db55bfa4e2c48486a7d7ce2"><code>32fc489</code></a> fix: malformed http urls (<a href="https://redirect.github.com/axios/axios/issues/11000">#11000</a>)</li> <li><a href="https://github.com/axios/axios/commit/b40ce498abfa10d90b873b4fd08f520afa5d2545"><code>b40ce49</code></a> chore(deps-dev): bump the development_dependencies group with 10 updates (<a href="https://redirect.github.com/axios/axios/issues/10">#10</a>...</li> <li><a href="https://github.com/axios/axios/commit/fe964f960ecb52c3e1155b0daf7be77541956b01"><code>fe964f9</code></a> docs: mark proxy config as Node.js only (<a href="https://redirect.github.com/axios/axios/issues/10995">#10995</a>)</li> <li><a href="https://github.com/axios/axios/commit/5f229d2d1f018d1db3dab6bbe034dbf3f9041b99"><code>5f229d2</code></a> chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 in the github-actions ...</li> <li><a href="https://github.com/axios/axios/commit/fae9d4e7db6a858c407c75e607a071c533c5c4f6"><code>fae9d4e</code></a> docs: clarify package update PR policy (<a href="https://redirect.github.com/axios/axios/issues/10992">#10992</a>)</li> <li><a href="https://github.com/axios/axios/commit/28ab2ced820e55192806c53472ab3eb0cbb68dc2"><code>28ab2ce</code></a> chore(deps-dev): bump the development_dependencies group with 2 updates (<a href="https://redirect.github.com/axios/axios/issues/10989">#10989</a>)</li> <li><a href="https://github.com/axios/axios/commit/a8e4f13aeecc45a3b8fab3ecfd9ddb5d70fb772b"><code>a8e4f13</code></a> fix(core): keep default validateStatus when request passes undefined (<a href="https://redirect.github.com/axios/axios/issues/10899">#10899</a>)</li> <li><a href="https://github.com/axios/axios/commit/614f4552a17de757d4171ad7c3bd38c9c1025fd8"><code>614f455</code></a> docs: publish v1.17.0 release notes (<a href="https://redirect.github.com/axios/axios/issues/10988">#10988</a>)</li> <li><a href="https://github.com/axios/axios/commit/6bb12c191f5380fad321322fb90216ae0dc36985"><code>6bb12c1</code></a> fix: custom auth headers not stripped on cross-origin redirects (<a href="https://redirect.github.com/axios/axios/issues/10892">#10892</a>)</li> <li>Additional commits viewable in <a href="https://github.com/axios/axios/compare/v1.16.1...v1.18.0">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> |
||
|
|
f18c664be2 |
fix(site): stack settings layouts on mobile (#27334)
## Problem On mobile viewports every settings shell renders a fixed 240px sidebar next to the content in a non-responsive flex row, leaving the content almost no width. The MCP Servers page is worst: its fixed-layout table cannot shrink, so the whole page collapses into a single cramped column. ## Changes - `Sidebar` component: full width below the `lg` breakpoint, `w-60` at `lg`+. - Six settings layouts (AI, Deployment, Organization, User, Workspace, Template) stack the nav above the content below `lg` and keep the previous side-by-side spacing at `lg`+. Content wrappers get `min-w-0` so flex children cannot force overflow, and horizontal padding tightens on small screens. - MCP servers table gets `min-w-[640px]` so the existing `overflow-auto` wrapper provides horizontal scrolling instead of colliding column headers. Tailwind class changes only; no component or behavior changes. ## Testing - `pnpm check` and `pnpm run lint:types` pass. - Dogfood UAT on a dev deployment: at 390x844 the MCP Servers, Deployment, Account, and Template settings pages stack nav-above-content with no horizontal body overflow and a scrollable MCP table; boundary verified stacked at 1023px and side-by-side at 1024px; at 1440x900 the layouts are pixel-identical to before (240px sidebar, 112px gap, 40px padding). Closes CODAGT-828. > Created by Mux, an AI agent, on Mike's behalf. |
||
|
|
a9fdf87a2f |
feat: add GET /groups/{group}/members/ai/spend (#27130)
## Description
Adds `GET /api/v2/groups/{group}/members/ai/spend?user_ids=...` (also available org-scoped at `/api/v2/organizations/{org}/groups/{groupName}/members/ai/spend`) to return per-member AI spend attributed to a group, along with each member's effective budget group and the applied spend limit when the queried group is their effective budget source.
In the UI, this endpoint is used alongside the existing `/api/v2/groups/{group}/members` endpoint. AI spend data is kept separate from that endpoint so that:
- Different concepts stay on different endpoints: identity (group members) vs. cost control (spend). Cost control is an additional feature layered on top of groups/orgs.
- Callers that don't need spend information don't pay for its computation.
UI flow:
1. Request `/api/v2/groups/{group}/members` → returns the group's members.
2. Request `/api/v2/groups/{group}/members/ai/spend?user_ids=...` with the IDs from step 1.
**Note:** Only current members of the queried group are returned. `spend_limit_micros` and `limit_source` are populated only when the queried group is the member's effective budget source (its own limit or a user override). `effective_group_id` is null when the member's budget resolves to a group in another organization, since an organization is treated as a tenant boundary.
<img width="2880" height="1904" alt="image" src="https://github.com/user-attachments/assets/33ed395d-d1a3-4b46-bb04-c8d3f41c8886" />
## Changes
- Add `codersdk.GroupMembersAISpend` and `GroupMemberAISpend` types, reusing the shared `AISpendPeriodWindow`.
- Add `GetGroupMembersAISpend` SQL query with a dbauthz per-row filter that mirrors `GET /api/v2/groups/{group}/members`.
- Add handler and routes under `/groups/{group}/members/ai/spend` (and the org-scoped alias) with a required `user_ids` query param (cap 100). Callers with more than 100 members are expected to batch across multiple requests.
- Add codersdk client method.
- Tests: dbauthz, raw SQL, endpoint, and role-access.
Closes https://linear.app/codercom/issue/AIGOV-471/backend-group-members-endpoint-with-members-spend
> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira
|
||
|
|
2adc8f5272 |
feat: add GET /organizations/{org}/groups/ai/spend (#27123)
## Description
Adds `GET /api/v2/organizations/{org}/groups/ai/spend?group_ids=...` to return per-group AI spend and configured limits for a set of groups in an organization.
In the UI, this endpoint is used alongside the existing `/api/v2/organizations/{org}/groups` endpoint. AI spend data is kept separate from that endpoint so that:
- Different concepts stay on different endpoints: identity (groups) vs. cost control (spend). Cost control is an additional feature layered on top of groups/orgs.
- Callers that don't need spend information don't pay for its computation.
UI flow:
1. Request `/api/v2/organizations/{org}/groups` → returns the organization's groups.
2. Request `/api/v2/organizations/{org}/groups/ai/spend?group_ids=...` with the IDs from step 1.
The groups endpoint from 1) is currently not paginated, but if pagination is added later, this design keeps the two responses in sync. This spend endpoint intentionally takes `group_ids` rather than paginating on its own, since it depends on the group set from step 1. Pagination could be added in the future, especially for Cost Control-focused pages.
<img width="2880" height="1460" alt="image" src="https://github.com/user-attachments/assets/ea83b74d-6a4f-45a6-af2f-1024e019da07" />
## Changes
- Add `codersdk.OrganizationGroupsAISpend` and `OrganizationGroupAISpend` types, plus a shared `AISpendPeriodWindow` embedded in the spend response.
- Add `GetOrganizationGroupsAISpend` SQL query with a dbauthz per-row filter that mirrors `GET /organizations/{org}/groups`.
- Add handler and route under `/organizations/{organization}/groups/ai/spend` with a required `group_ids` query param (cap 100). Callers with more than 100 groups are expected to batch across multiple requests.
- Add codersdk client method.
- Tests: dbauthz, raw SQL, endpoint, and role-access.
Closes https://linear.app/codercom/issue/AIGOV-466/backend-organization-groups-endpoint-with-groups-spend
> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira
|
||
|
|
9f4ddea571 |
feat: revoke MCP server OAuth grants at the provider on disconnect (#27300)
Closes [CODAGT-805](https://linear.app/codercom/issue/CODAGT-805/revoke-oauth-grants-at-the-source-for-mcp-servers). The experimental MCP server OAuth2 disconnect endpoint previously deleted only the stored token row, leaving the grant active at the OAuth provider. This PR adds provider-side token revocation while keeping local disconnect independent of provider availability. ## Changes - Add `mcp_server_configs.oauth2_revocation_url` in migration `000547`. The value can be configured manually, discovered from RFC 8414 metadata, and managed through the MCP server settings UI. Non-admin responses redact it with the other OAuth2 fields. - Revoke the refresh token first through the RFC 7009 endpoint, then fall back to the access token only for `unsupported_token_type`. Public clients send `client_id`; confidential clients use `client_secret_basic`. - Delete the local token transactionally before best-effort provider revocation. Callers without a token receive the same response for hidden and nonexistent config IDs, and provider failures return a generic warning without exposing provider response bodies. - Require HTTPS revocation endpoints except for HTTP loopback URLs. Redirects must preserve the POST and remain on the configured origin. Redirect errors omit provider-controlled paths and query strings so reflected token material cannot enter logs. - Treat `200 OK` and `204 No Content` as completed revocations. `202 Accepted` remains a failure because it does not confirm completion. - Prevent an in-flight refresh from recreating a token deleted by disconnect. Refresh persistence now uses an optimistic update keyed by token ID and `updated_at`; only the OAuth callback can create a token row. Refresh conflicts reload the current row or clear in-memory auth when disconnect deleted it. - Return `{token_revoked, token_revocation_error}` from disconnect, while retaining SDK compatibility with the legacy `204` response. The UI surfaces provider revocation failures as warning toasts. - Document revocation endpoint discovery, HTTPS requirements, and best-effort disconnect behavior. No token or no configured revocation URL returns `token_revoked: false` without an error, so disconnect remains idempotent. > Updated by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
9b3af629cd | fix: hide and reject chat models from disabled AI providers (#27070) | ||
|
|
34ed124478 |
fix(site): align React Compiler check scope with vite.config.mts (#27216)
## Stack Context First PR of a 6-PR stack that thins the agent instruction corpus (~4,800 lines down to ~2,800) by removing startup bloat, assigning each procedure one canonical owner, and fixing rules that drifted from reality. Split from #27203 for reviewability. ## Why? `site/vite.config.mts` compiles `src/pages/AIBridgePage/` with the React Compiler, but `site/scripts/check-compiler.mjs` did not include that directory. Compiler regressions in AIBridgePage were invisible to CI: code could silently bail out of compilation with no signal. The two lists had already drifted once, which is exactly how this class of bug recurs. ## What? - Add `src/pages/AIBridgePage/` to the check-compiler scope. Verified all 381 functions in scope compile cleanly. - Cross-reference the two lists with comments so the next person who edits one finds the other. This is the only behavioral (non-docs) change in the stack, which is why it sits at the bottom. > This PR was prepared by Mux (AI agent) on Mike's behalf. |
||
|
|
1ea61b976b |
fix(site): prevent slash menu from flashing at top-left corner when closed (#27326)
Typing `/` in the agent chat input opens the skills slash menu. Pressing Backspace to erase the `/` made the menu flash at the top-left corner of the app for a split second before disappearing. Radix keeps the popover content mounted through its exit animation, but the caret-positioned `PopoverAnchor` was unmounted in the same render that closed the menu. Without an anchor, the popper repositioned the still-visible closing content to the viewport origin. The anchor now stays rendered at the last known caret rect, so the menu holds its position while it animates out. Verified with a frame-by-frame position recorder in the browser: before the fix the closing menu jumped from the caret position to `(0, 4)`; after the fix it stays in place until unmount. Added a `BackspaceClosesMenuWithoutRepositioning` story that fails without the fix. > This PR was created by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
46d1823c0a |
feat: add workspace skills to agent chat slash menu (#25600)
> This Pull Request was updated by Mux working on behalf of Mike. Adds workspace skills to the agent chat slash menu, sourced entirely from the chat's pinned context resources (the single-chat GET response the page already fetches), the same inventory `read_skill` resolves from. No new API endpoint is introduced. Personal entries insert `/name`, or `/personal/name` when the name collides with a workspace skill or the chat's pinned context has not resolved yet; workspace entries insert `/workspace/name`. Qualified aliases stay searchable even when the displayed trigger is bare. Before a chat binds a workspace (new chat form, or a selected but unbound workspace), the menu lists personal skills only. Sending a message invalidates the chat detail query, and chatd broadcasts a context watch event when a first-turn bind pins the chat, so the menu picks up newly pinned context without a reload. Makes `UpdateChatWorkspaceBinding` a no-op when the requested workspace/build/agent binding is unchanged, preserving `updated_at` so chat list ordering and watch events stay stable. Includes regression coverage for the no-op binding guard, pinned-context skill mapping, collision qualification, and skills menu behavior. Refs [CODAGT-474](https://linear.app/codercom/issue/CODAGT-474/ux-improvements-for-coder-agents) (skills autocompleting in the editor). |
||
|
|
36e36e2048 |
fix(site): wrap workspace topbar controls on narrow viewports (#27313)
On mobile-width viewports the workspace page grew to ~1080px wide (390px viewport), pushing the schedule controls, status indicator, and action buttons off-screen. Users had to zoom out or scroll horizontally to reach Stop/Restart/Favorite/Share. The topbar header and the right-side controls group used non-wrapping flex rows, and every child is a `whitespace-nowrap` button, so the row's minimum width (~725px for the controls alone) forced the document wider than the viewport. ## Changes - `WorkspaceTopbar`: allow the topbar header and the right controls group to wrap; right controls stay right-aligned when they wrap onto their own row. - `WorkspaceActions`: allow the button row to wrap. - `TopbarData`: merge a caller-provided `className` (no existing caller passed one); the workspace breadcrumbs use it to wrap on very narrow screens. ## Verification Compared before/after with agent-browser on Storybook stories (`Workspace: Running`, `WorkspaceTopbar: Outdated / WithQuotaWithOrgs / Dormant / ConnectedWithMaxDeadline`): | Viewport | Before `scrollWidth` | After `scrollWidth` | |---|---|---| | 320 | 1080 (overflow) | 305 (fits) | | 390 | 1080 (overflow) | 375 (fits) | | 768 | 1080 (overflow) | 753 (fits) | | 1024 | 1080 (overflow) | 1009 (fits) | | 1440 | 1425 (fits) | 1425, pixel-identical (0% diff) | At widths >= 1280 the layout is unchanged (0% pixel diff at 1440 across the stories above). Between ~1080-1230px the controls now wrap onto a second right-aligned row instead of squeezing label text onto two lines inside a single row. Validation: `biome check`, `tsc --noEmit`, and `pnpm test:storybook` for `Workspace.stories.tsx` + `WorkspaceTopbar.stories.tsx` (36 passed). > This PR was prepared by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
1ac106255b | feat: add Anthropic 1M context window toggle for Agents model configs (#27257) | ||
|
|
2ac2295b1e |
fix: do not send or use stale init dynamic parameter state (#27283)
In summary, we use the init message if we have no autofill params. If we do, then we ignore the init message, send another message with the autofilled values, and then when we get *that* response, finally we render the form since we know we have good state. This eliminates the possibility of temporarily rendering with stale state. This is the same fix that was applied to the edit page, but on the create page this time. The only difference is that the create page does not need to wait on a build parameters query, instead it has to wait on the first message from the socket (to get defaults). This also makes one change where we would send the defaults in the init message. The server already knows the defaults so there is no need to send them. The advantage here is that we no longer need to wait for the first message, and it also fixes an issue where fields with blank values were getting validation errors because they were not filled out, before the user had a chance to actually fill them out. |
||
|
|
1453b4b1fc |
docs: document Bedrock mantle protocol (#27296)
Implements: https://linear.app/codercom/issue/AIGOV-518/add-docs-for-bedrock-mantle Follow-up to: https://github.com/coder/coder/pull/26745 |
||
|
|
3dd9265fa6 |
feat: add UI option to disconnect OAuth2 MCP credentials (#27299)
Closes [CODAGT-804](https://linear.app/codercom/issue/CODAGT-804/add-ui-option-to-revoke-oauth-mcp-credentials). Users could authenticate with an OAuth2 MCP server from the chat input, but there was no UI to disconnect those per-user credentials. The backend endpoint (`DELETE /api/experimental/mcp/servers/{id}/oauth2/disconnect`) already existed. ## Changes - Connected OAuth2 MCP rows in the chat input plus menu now show a disconnect icon button next to the enable switch. It opens a confirmation dialog; confirming calls the disconnect endpoint, shows a toast, and refetches MCP configs so the row reverts to the `Auth` button without a reload. - New `disconnectMCPServerOAuth2` API client method and react-query mutation that invalidates `mcp-server-configs`. - Storybook interaction tests: control visibility per auth state, cancel makes no API call, confirm calls the endpoint once, failed disconnect keeps the dialog open. - Hardened `TestMCPServerConfigsOAuth2Disconnect`: seeded tokens flip `auth_connected`, disconnect only removes the calling user's token, and repeat disconnect stays idempotent. The endpoint removes the token stored in Coder; it does not revoke the upstream OAuth grant, so the UI copy says "disconnect" rather than "revoke". Validated with the targeted Go test, Storybook tests (51 passed), tsc, biome, the react-compiler check, and a manual dogfood run (seeded token, disconnect/cancel/reconnect flows verified in the UI). > This PR was authored by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
9862f10484 |
feat(site): add Bedrock mantle protocol selector to provider form (#27156)
Implements: https://linear.app/codercom/issue/AIGOV-517/add-ui-for-bedrock-mantle Follow-up to https://github.com/coder/coder/pull/26745, which added AWS Bedrock **mantle** support to the backend and modeled it as a `protocol` field on the Bedrock provider settings. ## What changed - Adds a **Protocol** selector to the Bedrock provider form: InvokeModel (default) or Mantle. - The form is now protocol-aware: - **Model** / **Small-fast model** fields are shown only for InvokeModel. Mantle is a passthrough (the client sends the model at request time), so the fields are hidden and omitted from the saved settings. - **Endpoint** validation, placeholder, and hint switch per protocol. Mantle requires a `https://bedrock-mantle.{region}.api.aws/anthropic` URL; InvokeModel keeps the `https://bedrock-runtime.{region}.amazonaws.com` shape. The `/anthropic` suffix is required for mantle because the SDK appends `/v1/messages` to the base URL. ## Manual Testing Tested the following scenarios: 1. Creating a new Mantle provider — works. 2. Creating a new InvokeModel provider — works. 3. Verifying that an existing InvokeModel provider continues to work. 4. Upgrading an existing InvokeModel provider to Mantle — works. ## Screenshots ### InvokeModel <img width="1085" height="474" alt="image" src="https://github.com/user-attachments/assets/4c36b9b0-0eb8-4b17-80b7-e2112325f8d1" /> ### Mantle <img width="1082" height="357" alt="image" src="https://github.com/user-attachments/assets/e8caef26-83d1-4b7e-8f96-79079949e8f1" /> --------- Co-authored-by: Jake Howell <jake@hwll.me> |
||
|
|
b3ff4baeb9 |
fix: smooth compose loader to files page transition (#27277)
## Summary During the template builder compose flow, the transition into the template files page briefly flashed the wizard form again before the files page settled. Root cause: the loader was gated on `createMutation.isPending`. When the compose POST resolved, `isPending` flipped to `false` in the same commit that `onSuccess` navigated to the files page, so `TemplateBuilderPageView` repainted the wizard form for a frame before the route change committed and unmounted it. Fix: keep the loader mounted while the mutation is pending **or** succeeded (`createMutation.isPending || createMutation.isSuccess`). Since `onSuccess` always navigates away, the loader stays until the component unmounts, so the form never reflashes. The error path is unaffected (`isSuccess` stays false). Resolves DEVEX-561. https://github.com/user-attachments/assets/6d5ec04e-9f97-4864-bd18-e1e75055f079 ## Scope Targets the wizard form reflash only. Two adjacent items were identified during investigation and intentionally left out: - The destination files page briefly shows its own `<Loader />` while it fetches template files. Smoothing that requires prefetching before navigation and is a larger change. - The `justCreated` "Awesome, you just created a template!" alert is cleared by a mount effect, so it renders one frame then disappears. Arguably its own bug. Happy to follow up on either if wanted. ## Testing - Biome clean on the changed file. - Manual: build a template through the wizard and confirm the loader holds straight through to the files page with no form flash. ## Stack Stacked on top of #27276 (DEVEX-593). --- Generated by Coder Agents. |
||
|
|
3ddf7d3baa |
fix: stop the template builder build progress bar from looping (#27276)
## Summary The template builder's "Building your template" loader had a progress bar that animated 0→100% every 5s with an infinite repeat, so it visibly restarted over and over while a template built. It looked broken and was frustrating to watch. This replaces the looping fill with a single ease-out fill that decelerates toward 90% and holds until the request resolves and the loader unmounts. Since the loader is intentionally indeterminate and no progress is streamed to the browser, this also removes the now-dead `onUpdate` callback plumbing from the backend `waitForProvisionerJob` (its only caller passed `nil`). Resolves DEVEX-593. https://github.com/user-attachments/assets/6d5ec04e-9f97-4864-bd18-e1e75055f079 ## Commits - `refactor(coderd): drop unused onUpdate callback from waitForProvisionerJob` - `fix(site/src/pages/TemplateBuilder): stop build progress bar from looping` ## Testing - `go build ./coderd/` passes with the reduced `waitForProvisionerJob` signature. - Biome clean on the changed frontend file. - Storybook: `pages/TemplateBuilder/BuildingTemplateLoader` shows the bar fill once and hold, with no restart. <details> <summary>Implementation plan</summary> # DEVEX-593: Stop the build progress bar from looping repeatedly ## Problem While the template builder composes and imports a template, the FE shows `BuildingTemplateLoader`. Its progress bar animates from 0% to 100% over 5s with `repeat: Number.POSITIVE_INFINITY`, so it visibly restarts over and over. Users report this looks broken and is frustrating to watch while waiting. ## Decision (scope) Minimal fix only: **stop the loop**, plus remove the now-dead `onUpdate` plumbing from the backend. Since the UI is intentionally indeterminate and no progress signal is streamed, the callback serves no purpose and should be deleted rather than left as dead code. ### Why not "real sync" now - `POST /api/v2/templatebuilder/compose/template` is a single blocking request. It composes, bundles, inserts the provisioner job, then calls `waitForProvisionerJob(jobCtx, provisionerJob.ID, nil)` and only responds once the job completes. - The `onUpdate` callback runs server-side only. Nothing is streamed to the browser during the wait, so the FE has no progress signal to bind to. - A provisioner job exposes no numeric percentage. Only status transitions (`pending -> running -> succeeded`) and coarse log stages (`init/plan/graph/apply`) exist. Real sync would require converting the endpoint to a streaming protocol (SSE/WebSocket) plus FE rework, which is disproportionate for this 1-point ticket. ### Keep polling (do not switch to pubsub-block) The wait could technically block instead of poll: on completion `CompleteJob` publishes `ProvisionerJobLogsNotifyMessage{EndOfLogs: true}` on the job logs notify channel, so we could subscribe and wait for that message with the context timeout as a fallback. We deliberately do not do that here: correctness would require subscribe-before-completion plus an initial DB completion check to avoid a race, and Postgres LISTEN/NOTIFY is at-most-once (can drop under load), so a poll fallback would still be needed. The existing backoff poll (100ms -> 200ms -> 500ms -> 1s) is simple and robust for a short-lived synchronous request. ## Approach Replace the looping fill with a single, non-repeating ease-out fill that decelerates and approaches (but never reaches) ~90%, holding there until the request resolves and the loader unmounts. This reads as continuous forward progress for an unknown-duration operation and never restarts. The floating-icon animation is intentional ambient motion and is not in scope. ## Out of scope - Any behavioral change to how the endpoint waits (it still blocks on the job). - Streaming real job progress to the browser. - Changes to the floating-icon animation. </details> --- Generated by Coder Agents. |
||
|
|
529b2ead78 |
feat(site/src/pages/AgentsPage): show "Archived chats" sidebar heading when viewing archived chats (#26926)
In the agents sidebar, show "Archived chats" instead of "Chats" when the archive filter is set to `archived`. The heading reads the existing `sidebarFilters.archiveStatus` state, the same condition already used for the archived empty-state message. --- _This PR was opened by [Coder Agents](https://coder.com/) on behalf of @tracyjohnsonux._ --------- Co-authored-by: Coder Agents <noreply@coder.com> |
||
|
|
213f5ce606 | fix(site): redesign provider tri-state controls (#27288) | ||
|
|
457fa5afa3 | fix(site): move thinking settings to provider configuration (#27287) | ||
|
|
9d1e881093 | refactor(site/src/pages/AgentsPage): use model selector for personal overrides (#27229) | ||
|
|
baf4dfae4d |
fix(site/src/pages/TemplateBuilder): display TemplateCard/ModuleCard's official badge inline (#27036)
closes DEVEX-575 There are some screen widths / base template names where the official badge will break lines by itself as an orphan (see Google Compute Engine (Linux) in screenshot below). However, I personally prefer this over the current flex layout (compare with the screenshot in original issue) <img width="1840" height="1191" alt="image" src="https://github.com/user-attachments/assets/d5bee310-0202-4d45-aef7-767e457be051" /> Unfortunately ` ` only works if the entities on either side are both text--not text on the left + image on the right, which is what we have here. ^One alternative to prevent orphan badges is to split the base template name by words, then wrap the last word + the official badge in a span with `white-space: nowrap;`. But that feels a little overwrought to me; I like the clarity of continuing to just show `{name}` in the JSX. What do you guys think? |
||
|
|
0caaac5d27 |
fix: prebuild coderd before Playwright startup for e2e tests (#27136)
The test-e2e job could flake while Playwright waited for its webServer to become ready. CI already built site/e2e/bin/coder, but that binary was built before pnpm build and without the embed tag, so Playwright ignored it and started coderd with go run -tags embed instead. That put Go compilation, including frontend asset embedding, inside Playwright's webServer timeout. Local runs had a similar ordering trap. pnpm playwright:test invoked Playwright directly, and Playwright starts webServer before globalSetup, so the existing preflight build could not guarantee a binary existed before webServer startup. Build the E2E coder binary with the embed tag and make it depend on site/out/index.html. In CI, build the frontend first, then build the E2E binary, then run Playwright. For local runs, have pnpm playwright:test and pnpm playwright:test-ui run make site/e2e/bin/coder before invoking Playwright. Playwright now starts the prebuilt site/e2e/bin/coder binary and waits on the public /healthz endpoint instead of an authenticated API endpoint. This keeps compilation outside the webServer readiness timeout and makes the readiness probe quieter and more direct. I moved to /healtz because the existing endpoint was returning 401, which still means “server is up,” but it is a strange readiness signal. /healthz is explicitly public and returns 200 OK once the HTTP server is accepting requests. Caveat: running pnpm exec playwright test --config=e2e/playwright.config.ts directly bypasses the package script and therefore bypasses the prebuild. Use pnpm playwright:test or make test-e2e for the supported local flow. Because the site package scripts now call make, add make to knip's ignored system binaries. Tests: - pnpm lint:types - pnpm exec playwright test --config=e2e/playwright.config.ts --list - PATH="/opt/homebrew/opt/make/libexec/gnubin:/opt/homebrew/opt/gnu-getopt/bin:$PATH" make gen/mark-fresh - PATH="/opt/homebrew/opt/make/libexec/gnubin:/opt/homebrew/opt/gnu-getopt/bin:$PATH" pnpm playwright:test --list <!-- If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. --> |
||
|
|
cc11c8a536 |
feat: surface model content-filter refusals as a blocked chat error (#27118)
Blocked turns from a provider's content filter (Anthropic's `refusal` stop reason with empty content) previously ended silently on the "Thinking" spinner. They now end as a terminal `content_filter` error that renders as a "Response blocked" message with the provider's category and explanation. <img width="888" height="335" alt="image" src="https://github.com/user-attachments/assets/cef85a59-4091-4e62-9d45-1eb06748db48" /> Closes CODAGT-611 Follow-ups will involve implementing fallbacks, but this alone is pretty important |
||
|
|
8eaf4f507b |
feat: generate the known-models catalog and aigateway prices (#27146)
- Regenerates `prices.json` from models.dev. The seeder only upserts, so existing deployments keep delisted models. - Generate the frontend known-models catalog instead of hand-writing it. `make gen/aibridge-prices` fetches models.dev once - Moved patches to model definitions to separate `overrides.jq` which handles both `claude-sonnet-4-5` 200k context and 'aliasing' Fable 5 as Mythos 5. - Editorial choices of selection, order, aliases, and reasoning defaults live in `curation.json`. - Adds golden join tests with one error case per validation, a no-network drift test comparing curation to the checked-in artifact, and pinned invariants for the Anthropic thinking-mode split (the wrong side returns HTTP 400) and the sonnet-4-5 context pin. Adding a model is now one `curation.json` entry plus `make gen/aibridge-prices`, assuming it is present on models.dev. > This PR was authored by Coder Agents on Cian's behalf. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
b377bec5f4 | fix(site): replace ansi-to-html in the log viewer (#27206) | ||
|
|
61e52532c0 |
docs: wrap placeholder syntax in backticks in CLI help and swagger annotations (#27194)
## Problem
Generated reference docs (`docs/reference/cli/*`,
`docs/reference/api/*`) contained raw placeholder and JSON syntax that
came straight from Go CLI help strings and swagger annotations. HTML
renderers treat the angle-bracket tokens (`<team-slug>`, `<uuid>`,
`<KEY>`, etc.) as unknown tags and drop them, so readers see
broken/half-missing text today. The same strings also break MDX parsing.
## Fix
Wrap the placeholder/JSON syntax in backticks **at the source** (Go help
strings and swagger annotation comments), then `make gen`. Rendered docs
now show the placeholders as inline code instead of dropping them.
### Source changes
| File | Placeholder wrapped | Surfaces in |
|------|--------------------|-------------|
| `codersdk/deployment.go` | `` `<organization-name>/<team-slug>` `` |
`cli/server.md`, `coder --help`, settings UI |
| `codersdk/deployment.go` | `` `CODER_AI_GATEWAY_PROVIDER_<N>_*` ``, ``
`CODER_AI_GATEWAY_PROVIDER_<N>_<KEY>` `` | `api/schemas.md` |
| `cli/tokens.go` | `` `<type>:<uuid>` `` | `cli/tokens_create.md`,
`coder --help` |
| `coderd/aitasks.go` | `` `owner:<…>` ``, `` `organization:<…>` ``, ``
`status:<status>` `` | `api/tasks.md` |
| `coderd/exp_chats.go` | `` `pr_status:<…>` `` and sibling filter
tokens | `api/chats.md` |
| `coderd/provisionerdaemons.go`, `coderd/provisionerjobs.go` | ``
`{'tag1':'value1','tag2':'value2'}` `` | `api/organizations.md`,
`api/provisioning.md` |
Everything else in the diff (`coderd/apidoc/*`, `docs/reference/**`,
`*.golden`, `site/src/api/typesGenerated.ts`) is `make gen` output.
## Reviewer notes (the "considered pass" from the ticket)
- **Product-visible:** this changes `coder server --help` and `coder
tokens create --help` output, and the `server-config.yaml` reference
comment. Backticks in terminal help are literal but read fine as
placeholder markers.
- **Settings UI:** the `deployment.go` `Description` also renders in the
deployment settings page. If that field is not Markdown-rendered,
literal backticks will show there. Happy to drop the `deployment.go`
change if you'd rather keep the UI text clean and fix `server.md`
another way.
- **Out of scope here:** `docs/reference/cli/agent-firewall.md`
(`<host>`/`<glob>`) is generated from the external
`github.com/coder/boundary` module, not this repo. It needs an upstream
fix + module bump; not included in this PR.
<details>
<summary>Implementation notes / decision log</summary>
- Scope taken from DOCS-551: source-level backtick pass for generated
reference docs only. Hand-written Markdown fixes are tracked separately
(companion ticket).
- Swagger `@Param` descriptions are Go comments, so the existing `\|`
pipe-escaping in the chats `q` filter is preserved inside the new
backticks (still required for the Markdown table cell to render `|`).
- Verified after `make gen`: generated docs render placeholders as code
spans, table pipes intact; `gofmt` clean; changed Go packages build; no
emdash/endash introduced.
- Deliberately left the `AIProviderConfig` type-level doc comment
untouched because it does not surface in any generated doc (kept the
diff to doc-feeding comments).
</details>
Linear: DOCS-551
---
_Opened by Coder Agents on behalf of @nickvigilante._
---
## Evidence: placeholders dropped on the live docs site
Verified **2026-07-14** against the live site (`coder.com/docs`, i.e.
`main`, pre-merge) by loading each affected page in headless Chrome and
reading the post-hydration DOM (confirmed identical in the raw page
payload). Each simple `<token>` placeholder is parsed as an **empty
custom HTML element**, so the browser renders nothing for it and the
placeholder text disappears from the page.
### What readers see today (before this PR)
| Page (live) | Source Markdown | Rendered on the live site |
|-------------|-----------------|---------------------------|
| [`cli/server`](https://coder.com/docs/reference/cli/server) — OAuth2
GitHub Allowed Teams | `Structured as: <organization-name>/<team-slug>.`
| `Structured as: /.` |
|
[`cli/tokens_create`](https://coder.com/docs/reference/cli/tokens_create)
— `--allow` | `Repeatable allow-list entry (<type>:<uuid>, e.g.
workspace:1234-...).` | `Repeatable allow-list entry (:, e.g.
workspace:1234-...).` |
| [`api/tasks`](https://coder.com/docs/reference/api/tasks) — `q` | `...
status:<status>` | `... status:` (nothing after the colon) |
| [`api/schemas`](https://coder.com/docs/reference/api/schemas) —
AIBridgeConfig (`anthropic`/`bedrock`/`openai`) |
`CODER_AI_GATEWAY_PROVIDER_<N>_*` | `CODER_AI_GATEWAY_PROVIDER__*` |
| [`api/schemas`](https://coder.com/docs/reference/api/schemas) —
AIBridgeConfig (`providers`) | `CODER_AI_GATEWAY_PROVIDER_<N>_<KEY>` |
`CODER_AI_GATEWAY_PROVIDER__` |
[`api/chats`](https://coder.com/docs/reference/api/chats) (`q`) drops
five tokens the same way — `title:<substring>`, `diff_url:<url>`,
`pr:<number>`, `pr_title:<text>`, and the trailing `title:<value>`. The
live parameter description reads (note the dangling `title:`,
`diff_url:`, `pr:`, `pr_title:`):
```text
Search query. Supports title: (case-insensitive, quote multi-word values), archived:bool, has_unread:bool, pr_status:<draft|open|merged|closed> as repeated or comma-separated values, source:<created_by_me|shared_with_me>, diff_url: (quote values containing colons), pr: (exact PR number match), repo:<owner/repo> (case-insensitive substring match against git remote origin or URL), pr_title: (case-insensitive PR title substring). Bare terms are not supported; use title: for title filtering.
```
<details>
<summary>Raw rendered DOM from the live site (headless Chrome,
post-hydration)</summary>
```html
<!-- reference/cli/server -->
Structured as: <organization-name>/<team-slug>.</team-slug></organization-name>
<!-- reference/cli/tokens_create -->
Repeatable allow-list entry (<type>:<uuid>, e.g. workspace:1234-...).</uuid></type>
<!-- reference/api/tasks : only status:<status> drops; the /-containing tokens are escaped and survive -->
Search query for filtering tasks. Supports: owner:<username/uuid/me>, organization:<org-name/uuid>, status:<status></status>
<!-- reference/api/schemas : anthropic / bedrock / openai rows -->
Deprecated: Use Providers with indexed CODER_AI_GATEWAY_PROVIDER_<n>_* env vars instead.</n>
<!-- reference/api/schemas : providers row -->
Providers holds provider instances populated from CODER_AI_GATEWAY_PROVIDER_<n>_<key> env vars and/or the deprecated LegacyOpenAI/LegacyAnthropic/LegacyBedrock fields above.</key></n>
```
The parser auto-inserts closing tags
(`</team-slug></organization-name>`) and lowercases the tag name (`<N>`
becomes `<n>`), leaving `__` where `<N>_` used to be. Every wrapped
placeholder renders correctly as inline code on the [docs preview for
this
branch](https://coder.com/docs/@vigilante%2Fdocs-551-backtick-placeholder-syntax-in-generated-reference-docs-cli/reference/cli/server).
</details>
### Accuracy note — cases that do *not* drop on live
These render fine today, so they are **not** evidence of dropping (the
PR still wraps them for consistency / MDX-safety):
-
[`api/organizations`](https://coder.com/docs/reference/api/organizations)
and
[`api/provisioning`](https://coder.com/docs/reference/api/provisioning):
`{'tag1':'value1','tag2':'value2'}` renders verbatim — curly braces are
not an HTML tag.
- Tokens containing `/` or `|` are escaped by the renderer and stay
visible (as literal `<...>`): `<username/uuid/me>`, `<org-name/uuid>`,
`<owner/repo>`, `<draft|open|merged|closed>`,
`<created_by_me|shared_with_me>`. Backticks still improve their
readability, but they were never dropped.
|
||
|
|
3126306598 |
feat: add --aigateway-proxy-target flag (#27122)
Adds `--aigateway-proxy-target` option to `deploymentGroupAIGatewayProxy` that defines URL to which intercepted requests should be forwarded to. Forward URL used to be hardcoded to `coderAPI.AccessURL` pointing to embedded Gateway. With addition of standalone AI Gateway this needs to be configurable. Renamed `aibridgeproxyd.Server.coderAccessURL` and `coderAccessPort` -> `gatewayURL` and `gatewayPort` + option to better reflect reality. |
||
|
|
a567f6a89f | feat: allow admins to override the chat compaction model (#27151) |