mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
60161fd3757cde16e4fe26f8c0a9d60e023e826d
675
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
60161fd375 |
chore: update model prices to include more providers (#27837)
Adds the full set of supported provider types to `scripts/aibridgepricesgen` and updates stored model prices. Notes: * We need to rename a few keys from models.dev JSON to match our internal provider types. * `prices.json` is now marked as generated. --------- Co-authored-by: Susana Ferreira <susana@coder.com> |
||
|
|
c6cee10e8b |
feat: add per-model OpenAI Responses API toggle (#27683)
chatd hardcoded `WithUseResponsesAPI()`, so the provider SDK's static known-model list decided whether an OpenAI model spoke the Responses API or Chat Completions. A model absent from that list silently fell back to Chat Completions until the fantasy fork was patched. This exposes the SDK's `WithResponsesAPIFunc` hook as a per-model setting, `openai_config.use_responses_api`, stored in the existing `chat_model_configs.options` JSONB. Unset keeps the known-model list, `true` forces Responses, `false` forces Chat Completions. There is no migration. It sits in a new construction-time `openai_config` section rather than in `provider_options.openai` because it selects the API when the client is built, while `provider_options` holds per-request parameters. That placement is also load-bearing: a config setting only this field would otherwise materialize an OpenAI request-options struct and turn on provider-side response storage, since `Store` defaults to true there. Three places independently decided the transport and would silently disagree with the client actually built: | Site | Effect when it disagrees | | --- | --- | | `ModelFromConfig` | the transport being overridden | | `AcceptsFilePartMediaType` | text attachments dropped, since Responses natively accepts only images and PDFs | | `UsesResponsesOptions` | the SDK type-asserts the concrete options struct, so every OpenAI option is discarded | They share one predicate here, `chatopenai.UsesResponsesAPI`, with the override threaded to each. The rest of the stack removes that threading by resolving the transport once and carrying it. Compaction overrides and the quickgen debug model built clients without `ConfigOptions`, so they now pass it and pick up both this setting and the existing Anthropic beta headers. The toggle also makes transport-conditional option handling admin-switchable, so two hardening changes ride along. `ServiceTierFromChat` now maps every tier the codersdk enum advertises (`auto`, `default`, `flex`, `scale`, `priority`); it previously returned nil for `default` and `scale`, so flipping a model to Responses silently dropped a configured `service_tier` that the API accepts (fantasy forwards the value unchanged). And a new `TestProviderOptionsTransportParity` pins, per `provider_options.openai` field, which transport honors it, against a table in ARCHITECTURE.md, so a field honored on one transport and silently ignored on the other fails the test unless recorded as intentional. Review rounds also caught two lifecycle gaps around the new field. `isZeroChatModelCallConfig` now inspects `OpenAIConfig`, so a stored options blob whose only setting is this toggle survives into GET/list responses instead of reading as `model_config: null`; `TestIsZeroChatModelCallConfigCoversEveryField` sets each config field in isolation and fails if any field is invisible to the zero check. And the model editor's update path sends an explicit empty `model_config` when an edit clears the last field, since an omitted property preserves the stored options server-side; covered by the `EditClearingLastOptionSendsEmptyConfig` story. Azure keeps following the known-model list, because the Azure provider exposes no equivalent hook. The model editor renders Azure with the OpenAI option schema, so instead of shipping a visible but inert control, the option schema generator gains a `providers` struct tag that it emits as `visible_for_providers`. Gating uses the raw provider type rather than the alias table, so the control appears only for openai-typed providers. No hand-written frontend field: the editor renders it from the generated schema. Closes https://linear.app/codercom/issue/CODAGT-874/add-completionsresponses-api-toggle-in-model-editor > Mux prepared this PR on Mike's behalf. |
||
|
|
ba4779fc87 |
docs: lead with env vars in admin docs and add configuration reference (#26824)
## What & why Admin/setup docs lead with `coder server --flag` examples, but most operators configure Coder through `CODER_*` environment variables (system service, container, or Helm chart). There is no single page mapping a setting to its env var, CLI flag, YAML key, and default, so searching the docs for an env var name such as `CODER_PG_CONNECTION_URL` returns nothing. This adds a generated configuration reference and begins shifting admin docs to lead with the environment-variable form. ## Changes - **Generated configuration reference** (`docs/admin/setup/configuration-reference.md`): a searchable, per-setting list of every visible deployment option. Each option is a heading (grouped and nested by serpent group) followed by its description and the environment variable, CLI flag, YAML key, and default that apply to it. Generated from `codersdk.DeploymentValues` so it stays in sync. - **Generator + `make gen` wiring** (`scripts/configdocgen/`): new binary plus a Makefile target and `GEN_FILES` entry, mirroring the existing `clidocgen` / `auditdocgen` pattern. Output is host-independent (same env normalization as `clidocgen`). - **Demo conversion** (`docs/admin/users/github-auth.md`): inverted to lead with the `/etc/coder.d/coder.env` env-var form; the CLI-flag form becomes a closing note that links to the reference. H2 slugs preserved. - **Style guide** (`.claude/docs/DOCS_STYLE_GUIDE.md`): documents the env-var-first convention for admin/setup docs. - **Navigation**: manifest entry under Administration → Setup, plus a TIP callout on the setup index. ## Risk Docs + gen pipeline only; no runtime change. The page is regenerated by `make gen`; the `gen` and `check-docs` CI checks pass. ## Follow-up Several other admin pages still lead with flag walls. Recommend sweeping them incrementally in separate PRs rather than expanding scope here. <details> <summary>Implementation notes (provenance, conflict resolution, verification)</summary> - Continues prior work by @aslilac and @bpmct from the `kayla/docs-env-vars-first` branch. Both original commits are cherry-picked here with authorship preserved. - Rebased onto current `main`. Resolved two `Makefile` conflicts where `main` had since added the `feature-stages.md` gen target at the same locations; kept both targets (union) in `GEN_FILES`, `gen/mark-fresh`, and the recipe block. - The original branch's checked-in page predated recent `codersdk.DeploymentValues` changes, so it was **regenerated** against current `main` (adds `CODER_SCIM_USE_LEGACY`, the `Networking / Cluster` section with `CODER_CLUSTER_HOST`, `CODER_BOUNDARY_LOG_RETENTION`, and the AI Gateway description rename). The `gen` CI check enforces this stays current. - Fixed flag-link anchors for short-form flags (`--config`, `--log-filter`): the generator derives the anchor from `FlagShorthand` to match `clidocgen`'s heading (e.g. `#-l---log-filter`). - `linkspector` ignores the AWS Bedrock base URL that appears as an illustrative `<region>` placeholder in an option description, consistent with the existing `openai.com` ignore patterns. </details> <details> <summary>Configuration reference layout (2026-07-08 update)</summary> Reworked the reference from a wide table into a nested, per-setting list so it fits without horizontal scrolling and stops repeating the group name in every heading: - **List, not table.** Each option renders as a heading, its description, and a bullet list of only the configuration methods that apply to it (non-applicable methods are omitted instead of shown as `-`). - **Nested sections.** Sections nest by the serpent group hierarchy, so `Email / Email Authentication` becomes `Email` (h2) with an `Email authentication` (h3) subsection instead of a redundant flat title. - **Shorter, sentence-case headings.** The redundant group prefix is stripped from each option name and the remainder is lowercased to sentence case, preserving acronyms and mixed-case tokens (`URL`, `TLS`, `OAuth2`, `GitHub`) plus a small proper-noun allowlist (`Coder`, `Terraform`, `Honeycomb`, `Anthropic`, `Bedrock`, ...). Example: `AI Gateway Send Actor Headers` becomes `Send actor headers`. - **Deprecated options** sort to the end of each section and lead with an emphasized **Deprecated** marker. Headings stay clean (no `(deprecated)` suffix) so their anchors remain stable. - **Section intros** render from a group's `Description` when the source defines one (e.g. DERP); no hand-maintained prose or links are introduced. All transformations run in pure Go at `make gen` time (no AI at generation time). Generation is idempotent, and `markdownlint` and `golangci-lint` both pass. </details> --- 🤖 Opened by Coder Agents on behalf of @nickvigilante. Continues work by @aslilac and @bpmct. --------- Co-authored-by: Kayla (via Coder Agents) <kayla@coder.com> Co-authored-by: Coder Agents <noreply@coder.com> Co-authored-by: Ben Potter <me@bpmct.net> |
||
|
|
18128b7b52 |
docs: add standalone AI Gateway docs (#27592)
Documents standalone AI Gateway deployment, Gateway key authentication, monitoring, and the updated embedded vs standalone topology in the AI Gateway docs. --------- Co-authored-by: Cian Johnston <cian@coder.com> |
||
|
|
8ea2586189 |
feat: add chat lifecycle hook dispatch backend (#27401)
Adds the chat lifecycle hook wire contract and dispatch plumbing, first PR of the lifecycle hooks stack (followed by #27428, #27429, #27430). - `codersdk/x/agenthooks`: event and response wire types, JWT creation and verification with the shared secret (HS256, request body digest, expiry and not-before freshness checks), and an HTTP handler helper so consumers only implement the events they use. The `codersdk/x` location marks the consumer SDK as experimental. - `coderd/x/agenthooks/dispatch`: a stateless dispatcher that signs and posts hook events, enforces a concurrency cap under one configured timeout that bounds both the capacity wait and both post attempts, retries one connection failure with the same JWT, sends a distinctive `coderd-agenthooks/<version>` User-Agent, and records Prometheus metrics. Delivery is at least once; consumers own durable decision state, audit records, and deduplication keyed by the stable payload identifiers. Nothing is persisted by Coder. - Response bodies decode strictly: unknown fields, duplicate JSON keys (including inside `input_override`), and trailing data fail the dispatch closed as protocol errors instead of silently reading as allow. - `coderd/util/xnet`: shared timeout and connection error classification used by the dispatcher retry logic. Transient HTTP/2 stream aborts count as connection errors, so the documented single retry also applies to h2 consumers, which is the shape Go's default transport negotiates against any TLS consumer. Deterministic protocol failures stay terminal. Only the struct form of a stream error is matched, because `net/http` bundles its own HTTP/2 types and `h2_error.go` bridges only that shape. - `scripts/agenthooks-server`: a reference consumer that logs events and demonstrates consumer-owned pre-tool decision deduplication. It requires an explicitly configured JWT audience rather than deriving one from the request, and its startup output names the mode it is running in so an operator can see that the example policy flags need `-log-only=false`. - `scripts/apitypings`: generate TypeScript types for the hook wire contract. Dispatch failures log without the error's stack frames, since a failed dispatch is an expected, operator-visible condition. Nothing dispatches these events yet; chatd wiring lands in #27429. > This PR was written by Mux, an AI coding agent, on Mike's behalf. |
||
|
|
c351280a37 |
feat: add Prometheus metrics for AI Governance cost control (#27490)
## Description Adds Prometheus metrics for AI budget cost control, emitted by the aibridged server under the `cost_control` subsystem (full names are prefixed `coder_ai_gateway_`). - `blocked_requests_total` (counter) — labels: `group_id` - `blocked_users` (gauge) — labels: `group_id` - `unpriced_requests_total` (counter) — labels: `provider`, `model` - `enforcement_duration_seconds` (histogram) — labels: `outcome` ## Changes - Add `GetOverBudgetUsersPerGroup` query (plus dbauthz/dbmetrics/dbmock wiring) to count over-budget users per effective group. - Add a background collector that refreshes the `blocked_users` gauge on an interval, started only when Prometheus is enabled. - Wire `Metrics` through the aibridged server, coderd API, `cli/server.go`, and the enterprise AI gateway handler; recording is nil-safe when metrics are unset. Closes https://linear.app/codercom/issue/AIGOV-296/add-prometheus-metrics-for-cost-control > [!NOTE] > Initially generated by Claude Opus 4.7, modified and reviewed by @ssncferreira |
||
|
|
591f357574 |
chore: remove releaser v2 flow and drop v1 naming (#27421)
## Summary Removes the GitHub Actions-driven releaser **v2** pipeline so the interactive release wizard is the only release path, and drops the `v1` naming now that it is the sole implementation. ## Changes - Delete `.github/workflows/tag-and-release.yaml` (the v2 workflow). - Delete `scripts/releaser/v2/`. - Move `scripts/releaser/v1/` into `scripts/releaser/` as `package main`. - Rewrite `scripts/releaser/main.go` to a single wizard command: drop the `--legacy` flag and the v2 `rc`/`branch`/`release` subcommands and hidden CI compat commands. `--dry-run` is preserved. - Update `scripts/release.sh` to run `go run ./scripts/releaser "$@"` (no `--legacy`). The legacy `release.yaml` workflow (triggered by `scripts/release.sh`) is unchanged and remains the release pipeline. ## Validation - `go build ./scripts/releaser/...` - `go test ./scripts/releaser/...` - `go vet` + `golangci-lint run ./scripts/releaser/...` - `gofmt -l` clean > [!NOTE] > The GPG signing key check removal is handled in a stacked follow-up PR based on this branch. <details> <summary>Implementation plan</summary> - v2 flow = `scripts/releaser/v2/` + `.github/workflows/tag-and-release.yaml` (uses `go run ./scripts/releaser prepare-release|generate-notes`). `v2` was imported only by `main.go`; the workflow was referenced nowhere else. - v1 flow = interactive wizard in `scripts/releaser/v1/`, reached via `--legacy`, driving `release.yaml` (triggered by `scripts/release.sh`). - No `docs/` referenced the releaser tool or these workflows. - Steps: delete the v2 workflow and package; move `v1/*` up to `scripts/releaser/` (`package main`, including test files); rewrite `main.go` to a single wizard command; update `release.sh`. </details> --- Generated by Coder Agents on behalf of @f0ssel. |
||
|
|
76b35edaff |
ci: backport to ESR and ESR-1 release branches (#27460)
## What Extend the backport workflow so the `backport` label fans out to **every actively supported release channel**, not just the latest three minors. Target branches are now the union of: - the latest 3 `release/2.X` branches (mainline `n`, stable `n-1`, security `n-2`), and - the active **ESR** and **maintenance ESR (ESR-1)** branches. The set is de-duplicated, so a branch that is both stable and ESR (today `release/2.34`) is backported once. Dry-run against the current branch list yields `release/2.29`, `release/2.33`, `release/2.34`, `release/2.35`. ## Why ESR / ESR-1 are designated biannually and can sit well below the top-3 window, so the previous `head -3` heuristic silently skipped them (e.g. the maintenance ESR `release/2.29`). The current ESR was only covered by coincidence when it happened to equal stable. ## Changes - Add `scripts/release_channels/esr_versions.txt` as the single source of truth for active ESR minors. - `scripts/update-release-calendar.sh` now reads that file instead of a hardcoded `ESR_VERSIONS` array (calendar output verified unchanged). - `backport.yaml` `detect` job unions the latest 3 branches with the ESR branches (existence-checked, warns and skips missing ones) and de-duplicates. - Backport PRs now get a `backport/v<version>` label, mirroring `cherry-pick.yaml`, with `issues: write` added to create the label. ### Resilience to partial failures Even with the independent matrix (`fail-fast: false`), a single branch's job could previously abort without leaving anything behind, forcing the remaining branches to be backported entirely by hand. Fixed so each branch always ends with a PR (real or placeholder): - Label, assignee, and reviewer are attached **after** the PR is created, as best-effort steps. Requesting review from / assigning the PR author is rejected by GitHub, which previously aborted `gh pr create` under `set -e` and left no PR. - Idempotency now keys off an existing backport **PR** rather than the branch, and an existing backport branch is reused instead of bailing, so a re-run recovers a branch that was pushed before its PR was opened. - The workflow now comments on the original PR with each created backport link, flagging conflicts that still need manual resolution. - Conflicting cherry-picks continue to open a placeholder PR with copy-paste resolution steps. ## Validation - `actionlint`, `shellcheck -x`, and `zizmor` all pass. - Re-ran `update-release-calendar.sh`; ESR statuses (`2.29 Extended Support Release`, `2.34 Stable (ESR)`) are identical after the refactor. - Dry-ran the detection logic against the live branch list (see set above). <details> <summary>Implementation plan</summary> # Plan: Backport to all supported release channels (mainline, stable, security, ESR, ESR-1) ## Goal The backport GitHub Action should open cherry-pick PRs against every actively supported release branch: | Channel | Meaning | Example today | |-------------------------|-----------------------------|----------------| | Mainline | last release (n) | `release/2.35` | | Stable | n-1 | `release/2.34` | | Security Support | n-2 | `release/2.33` | | ESR | current Extended Support | `release/2.34` | | Maintenance ESR (ESR-1) | previous ESR still patched | `release/2.29` | All channels map to `release/2.X` branches. ## What we targeted before `.github/workflows/backport.yaml` took the exact `release/2.X` branches, sorted by minor descending, and kept the top 3 (mainline/stable/security). ESR and ESR-1 are not derivable from version ordering, so the maintenance ESR was silently skipped. ## Source of truth for ESR branches `scripts/update-release-calendar.sh` already encoded the active ESR minors (`ESR_VERSIONS=(29 34)`), driving the release calendar. Rather than maintaining a second list, this list was extracted into a shared data file consumed by both the calendar script and the workflow. ## Changes 1. Extract the ESR minors into `scripts/release_channels/esr_versions.txt`; update `update-release-calendar.sh` to read it. 2. Extend the `detect` job to emit the union of the top-3 branches and one `release/2.<minor>` per ESR entry, existence-checked and de-duplicated. 3. Add per-release `backport/v<version>` labels (with `issues: write`), mirroring the cherry-pick workflow. ## Assumptions - Major version is always `2` (matches existing code). - The ESR list is maintained manually when ESR versions change. - `cherry-pick.yaml` stays single-branch and is out of scope. - Missing ESR branches are skipped with a warning, not a failure. </details> --- *Opened by Coder Agents on behalf of @f0ssel.* |
||
|
|
8a3fb04510 |
feat: add Helm chart for standalone AI Gateway (#27256)
Adds the `coder-ai-gateway` Helm chart for deploying the Coder AI Gateway as a standalone Kubernetes workload. Adds the coder-ai-gateway Helm chart for deploying the Coder AI Gateway as a standalone Kubernetes workload. The chart supports AI Gateway keys from an existing Secret or environment configuration, Coder connectivity through CODER_URL, listener and Coder-facing TLS, and optional Service, Ingress, and Gateway API HTTPRoute resources. Integrates the chart with existing Helm build, lint, golden generation, release artifact, Helm repository, and OCI publishing workflows. |
||
|
|
77582be805 |
fix: close <b> tag in generated audit log table header (#27293)
## What The audit log resource table header in `docs/admin/security/audit-logs.md` was emitted as `<b>Resource<b>`: a second opening `<b>` instead of a closing `</b>`. Because the bold element never closes, Markdown/HTML renderers can bold content well beyond the header cell. The page is generated (`<!-- Code generated by 'make docs/admin/security/audit-logs.md'. DO NOT EDIT -->`), so the fix belongs in the generator, `scripts/auditdocgen/main.go`, with the doc regenerated from it. ## Changes - `scripts/auditdocgen/main.go`: emit a closing `</b>` instead of a second `<b>` in the table header row. - `docs/admin/security/audit-logs.md`: regenerated with `make docs/admin/security/audit-logs.md`; only the header cell changes. ## Verification <details> <summary>Regenerated doc and local checks</summary> Header cell before (unclosed tag): ```text | <b>Resource<b> | ... ``` Header cell after (balanced tag): ```text | <b>Resource</b> | ... ``` - `make docs/admin/security/audit-logs.md` regenerates the page from the fixed generator and changes only the header cell (single line; the table stays aligned). - Local `make pre-commit` passed with `GEN_SKIP_GOLDEN=1` (this workspace has no Docker daemon for the golden-file gen step, which this change does not touch): `gen`, `fmt`, `lint/go`, `lint/ts`, `lint/markdown`, `lint/typos`, `lint/emdash`, and the slim binary build all green. </details> ## Linear DOCS-580: https://linear.app/codercom/issue/DOCS-580/fix-unclosed-b-tag-in-generated-audit-logs-table-header --- This PR was created using AI (Coder Agents) on behalf of @nickvigilante, who is accountable for its contents. See the [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING). |
||
|
|
f7481c5d08 |
feat: Add full text search over chat messages (#27126)
Closes CODAGT-721 Closes CODAGT-722 Closes CODAGT-723 Closes CODAGT-724 Closes CODAGT-725 This PR adds the database and API pieces necessary to support full-text chat message search. - Adds required chat schema for full-text search - Adds dbpurge job to populate search_tsv in the background - Adds `search` parameter to GetChats query - Adds `search` filter to `searchquery.Chats` - Wires chat search filter into chats API > Implemented by Coder Agents, reviewed and tested by a human. |
||
|
|
c84aa564ba |
docs: normalize code-fence languages for Shiki compatibility (#27161)
Normalizes non-standard code-fence language tags across `docs/**` so a strict highlighter (Shiki, used by Fumadocs) won't fail the build on an unrecognized language, and unifies redundant synonym tags onto one canonical form per language. The current renderer (Speed-Highlight) detects the language from the code content, not the fence label, so this drift wasn't visible until now. ## Changes - `hcl` -> `tf` (199 fences, including indented ones nested in numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**` is actually Terraform resource/data/provider syntax, so the more specific `terraform` grammar is correct for all of them. `tf` is Shiki's own alias for that grammar, and it's also what GitHub's own markdown renderer resolves to the same HCL/Terraform highlighting. - `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a registered file extension (`.ps` isn't), so `ps1` renders identically to `powershell` there today while bare `ps` would silently lose highlighting. - `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files) - `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text fallback either way, just shorter. - `Dockerfile` -> `dockerfile` (lowercase) - `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all three to a single shell grammar; this was already the style guide's stated preference, just not enforced across the existing corpus until now. - `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki and GitHub. - `jsonc` -> `json` (1 fence). The block has no comments or trailing commas, so it doesn't need the comments-capable grammar. - `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`). Verified the actual content tokenizes identically under both grammars, and a sibling block in the same file already needs `tsx` for real JSX, so unifying to one tag is safe for this file. Documented a caveat: `tsx` mis-tokenizes the legacy angle-bracket type-assertion syntax (`<Type>value`), which is invalid in real `.tsx` files anyway, so use `value as Type` instead. - `yml` -> `yaml` (1 fence) - Updated `docs/.style/style-guide/formatting.md` to document all canonical tags `promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki doesn't bundle a grammar for either, so they need a custom grammar registration when the site adopts Shiki, rather than degrading to `txt`. Tracked as follow-up work under DOCS-118 and [DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting) (promql). Does not touch `offlinedocs/`. Linear: [DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs) <details> <summary>How the fence tags were verified</summary> Each tag was tested against a real `shiki@latest` highlighter instance (`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's `@wooorm/starry-night` grammar sources (the renderer that actually displays these `.md` files today, in repo browsing and PR diffs), since that's what determines whether brevity is safe before Shiki adoption: ```text FAIL env -- Language `env` is not included in this bundle. FAIL Dockerfile -- Language `Dockerfile` is not included in this bundle. FAIL promql -- Language `promql` is not included in this bundle. FAIL caddyfile -- Language `caddyfile` is not included in this bundle. FAIL pwsh -- Language `pwsh` is not included in this bundle. FAIL output -- Language `output` is not included in this bundle. ``` `hcl` doesn't error in Shiki, since it's a real grammar, but that's exactly the trap: it was silently rendering every fence with the generic HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged fence in `docs/**` was manually checked against `origin/main` and is genuinely Terraform content. For `ts`/`tsx`, tokenizing the actual doc content confirmed identical output under both grammars; a synthetic test with the legacy angle-bracket cast syntax confirmed `tsx` degrades on that specific construct, which the style guide now calls out. The first normalization pass only matched fence tags at column 0 (`^```tag$`), missing tags indented inside numbered/bulleted lists. A follow-up pass caught the remaining occurrences at any indentation level. </details> --- *This PR description and the underlying changes were prepared with Coder Agents assistance.* |
||
|
|
2bea8fb382 |
fix(scripts/releaser/v1): remove doubled "v" in release calendar latest release link (#27260)
## Problem
The interactive releaser (`scripts/releaser`) renders the "Latest
Release"
cell of the release calendar with a doubled version prefix, e.g.
`[vv2.35.0](.../tag/v2.35.0)`.
`version.String()` already returns a `v`-prefixed string (e.g.
`v2.35.0`),
but `updateCalendar` wrapped it in a `"[v%s]"` template, so the link
label
gained a second `v`. The tag URL was already correct because release
tags
carry the `v` prefix.
## Fix
Drop the extra `v` from the label template (`"[v%s]"` → `"[%s]"`). The
URL is
unchanged.
- Label before: `[vv2.35.0]`
- Label after: `[v2.35.0]`
## Test
Added `scripts/releaser/v1/docs_test.go`:
- `TestUpdateCalendarLatestReleaseVersionPrefix` asserts the
`LatestRelease`
cell for a matching row on both a patch and a minor release. It fails on
the
old code (`[vv2.35.x]`) and passes with the fix.
- `TestUpdateCalendarNotReleasedRowName` covers the `Not Released` →
`Mainline`
promotion and the major.minor "Release name" link (patch omitted).
<details>
<summary>Investigation notes</summary>
- Entry path: `scripts/release.sh` → `go run ./scripts/releaser
--legacy` →
`runRelease` → `promptAndUpdateDocs` → `updateReleaseDocs` →
`updateCalendarFile` → `updateCalendar` (`scripts/releaser/v1/docs.go`).
- Root cause in `updateCalendar`: `fmt.Sprintf("[v%s](%s)",
newVer.String(), ...)`
combined with `version.String()` returning `v%d.%d.%d`.
- Only the link label was affected; the `releaseTagURLFmt` URL was
correct
because tags are `v`-prefixed.
- The standalone `scripts/update-release-calendar.sh` is a separate
implementation and is not affected (it strips the `v` before re-adding
one).
- Companion PR for `release/2.35` (file `scripts/releaser/docs.go`):
#27259.
</details>
---
This PR was generated by Coder Agents.
|
||
|
|
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> |
||
|
|
1cc230b43a |
refactor: extract docgen env prep into a shared package (#26827)
## What `clidocgen` and the new `configdocgen` (coder/coder#26824) both carried a byte-identical `prepareEnv()` that unsets `CODER_*` and pins `CLIDOCGEN_*` / `TMPDIR` so generated docs don't embed the generating host's home directory. This extracts it to `scripts/docgenenv.Prepare()` and migrates `clidocgen`. ## Why Duplication flagged during review of #26824. `configdocgen` adopts the shared helper in that PR, removing its copy. ## Risk Behavior-preserving: regenerating the CLI reference (`make docs/reference/cli/index.md`) yields no diff, and `make pre-commit` passes (`lint/go`, `lint/ts`, `build`). A focused unit test pins the `Prepare()` contract, and `_test.go` files are excluded from `CLIDOCGEN_INPUTS` so test edits don't mark the generated docs stale. <details> <summary>CI status — blocked by an unrelated <code>main</code> breakage (#24993)</summary> All red checks on this PR are inherited from `main`, not caused by these changes. This PR touches only `Makefile` and `scripts/{clidocgen,docgenenv}`; it does not touch Helm. `main` went red at `d0f68cb9b0` ("feat: add listenerset", #24993, merged ~18:26 UTC). The committed `helm/coder/tests/testdata/listenerset*.golden` files don't match what `helm template` renders, so: - **`gen`** regenerates those goldens, and the unstaged-files check fails. - **`test-go-pg` (ubuntu-latest, pg-17) and `test-go-race-pg`** fail only on `TestRenderChart/{coder,default}/listenerset[_redirect]` (golden mismatch; the test prints "Run with -update to update golden files"). The same `test-go-pg` job passes on macOS and Windows, where the Helm render test is skipped, and `scripts/docgenenv` reports `ok` on the failing runners. Base commit `14a61041d9` was green; `main` is red from `d0f68cb9b0` onward. These checks clear once `main` is fixed and this branch is updated. `fmt`, `lint`, `Storybook`, `check-build`, and `test-e2e` are green. </details> --- 🤖 Opened by Coder Agents on behalf of @nickvigilante. --------- Co-authored-by: Cian Johnston <cian@coder.com> |
||
|
|
bfbacd64f4 |
refactor: consolidate release tooling into a single releaser command (#27034)
## What Consolidates the two separate release programs into a single command at `scripts/releaser`: - `scripts/releaser/v1/` — the former interactive releaser (package `v1`). - `scripts/releaser/v2/` — the former `scripts/release-action` CI tool (package `v2`). - `scripts/releaser/main.go` — new entrypoint. Runs the **v2** tooling by default and the **v1** interactive wizard with `--legacy`. ## CLI shape Three documented subcommands, each backed by v2 `prepare-release` with the release type baked in: - `releaser rc` — tag a release candidate - `releaser branch` — cut a new release branch and tag its first RC - `releaser release` — tag a stable release or patch The former release-action verbs (`calculate-version`, `prepare-release`, `generate-notes`, `publish`) are retained as **hidden** top-level commands with identical flags and stdout, so `tag-and-release.yaml` migrates with a path-only change (`scripts/release-action` -> `scripts/releaser`). `--legacy` runs the v1 wizard and is mutually exclusive with the subcommands. `scripts/release.sh` now launches `releaser --legacy`. All file moves are rename-detected by git, so the per-file diff is just the package declaration. ## Testing - `go build ./scripts/...`, `go vet ./scripts/releaser/...`, `go test ./scripts/releaser/...` - `golangci-lint run ./scripts/releaser/...`, `make lint/emdash`, `shellcheck`, `actionlint` - Smoke: `releaser --help` shows only rc/branch/release; hidden verbs still run; `releaser rc --ref main --dry-run` emits the same JSON contract; `--legacy rc` errors cleanly. <details> <summary>Implementation plan</summary> # Plan: Consolidate release tooling into a single `scripts/releaser` command ## Goal Merge the two separate release programs into one binary at `scripts/releaser`: - `scripts/releaser/v1/` — the current interactive releaser (package `v1`). - `scripts/releaser/v2/` — the current CI `scripts/release-action` (package `v2`). - `scripts/releaser/main.go` — new entrypoint (package `main`). - Uses v2 by default, v1 with `--legacy`. - Exposes 3 subcommands: `rc`, `branch` (cut release branch), `release`. ## Design decision (Option A, chosen) The workflow needs `prepare-release`, `generate-notes`, and `publish` invokable separately (a build happens between prepare and publish). The latter two are version-driven and type-agnostic, so they do not map cleanly onto `rc`/`branch`/`release`. - Visible subcommands `rc`, `branch`, `release` run v2 `prepare-release` with the type baked in and print the same JSON. - Hidden verbs `calculate-version`, `prepare-release`, `generate-notes`, `publish` keep byte-identical flags/stdout, so the workflow change is path-only. Lowest risk; honors "3 subcommands" from a UX perspective. ## `--legacy` semantics - `releaser --legacy` runs the v1 interactive wizard (preserves today's behavior; the wizard auto-detects RC vs release from the branch). - `--legacy` is mutually exclusive with the subcommands (clear error if combined), because v1 auto-detects type and cannot cut a branch. ## Work items 1. Create `v1` and `v2` packages via `git mv`, renaming `package main`. Move the `owner`/`repo` consts into each package. Add `v1.Run(inv, dryRun)` (old wizard `main()` body) and v2 command builders (`CICommands`, `TypeCommand`) so internals stay unexported. 2. New `scripts/releaser/main.go`: top-level `releaser` with `--legacy`, the 3 subcommands, and the hidden compat verbs; delegates to `v1.Run` for legacy. 3. Update references: `tag-and-release.yaml` (3 command paths + header comment) and `scripts/release.sh` (`--legacy`). 4. Verify: build, vet, test, `go run` smoke tests, fmt, lint. 5. Open a single PR from a feature branch. ## Risks / notes - stdout contract for rc/branch/release and the hidden verbs must stay identical (workflow parses stdout); logs go to stderr. - Patch releases from pre-existing `release/X.Y` branches run those branches' own (old) workflow + `scripts/release-action`, so they stay self-consistent. New releases cut from branches containing this change get the new workflow + `scripts/releaser`. No forwarding stub needed since code and workflow ship together. </details> --- This PR was created by Coder Agents on behalf of @f0ssel. |
||
|
|
fc188fdaee |
fix: create agent firewall sessions without requiring agent read access (#26990)
## Overview Part of the **boundary correlation** feature. Fixes lazy creation of `boundary_sessions` rows so it works within the agent's RBAC constraints, and consumes the new `ConfinedProcessName` field reported by boundary. Pairs with coder/boundary#206, which adds `ConfinedProcessName` to `ReportBoundaryLogsRequest`. This branch bumps the `github.com/coder/boundary` module to pick up that work. ## Problem `ensureSession` did a pre-insert existence check via `GetBoundarySessionByID`. Agents are **not permitted to read boundary sessions**, so that read path is not viable when the session is created from an agent-reported log batch. ## Changes - **Remove the pre-insert read.** `ensureSession` now inserts directly and treats a primary-key unique violation as success, covering sessions already created by a prior batch, a reconnection, or another coderd replica — without requiring read access. - **Per-connection guard.** Add a mutex-protected `ensuredSessions` set so repeated log batches on the same connection skip the existence check and insert entirely, touching the database only for the logs. On a transient insert failure the session is left unmarked so the next batch retries. - **Consume `ConfinedProcessName`.** Pass `req.GetConfinedProcessName()` through to the session insert. - **Bump boundary module** from `v0.9.0` to `v0.9.1-0.20260706095856-35ba90f9e8b2`. - **Tests.** - Add `TestReportBoundaryLogsAgentRBAC` (`coderd/boundary_logs_test.go`), an integration test that connects as a real workspace agent, verifies the session and log are persisted under agent RBAC, and asserts the agent subject cannot read boundary sessions — guarding against reintroducing a pre-insert read. - Add `TestReportBoundaryLogsSessionGuard` (session inserted once across two batches, logs inserted per batch) and `TestReportBoundaryLogsSessionRetriedOnError` (insert retried after a transient error). - Regenerate `agent-firewall` CLI docs/golden files and adjust the clidocgen template to render the YAML path when a flag has no long name. > 🤖 This PR was opened by Coder Agents on behalf of @SasSwart. |
||
|
|
b21e0717d5 |
feat: remove chat chain mode (#26980)
Removes OpenAI Responses "chain mode" from chatd. Closes CODAGT-445.
- Deletes `chatopenai/responses.go` (chain detection, activation, prompt filtering, response ID extraction) and its tests.
- Deletes the `ChainBroken` classification in `chaterror` and the chatloop retry bookkeeping that disabled chain mode mid-generation.
- Drops the `chain_broken` label from the `coderd_chatd_stream_retries_total` metric.
- Stops reading and writing `chat_messages.provider_response_id`
- Deletes the dead `ClearChatMessageProviderResponseIDsByChatID` query. Dropping the column is a follow-up migration.
- Deletes three chatloop hooks no caller sets (`ReloadMessages`, `DisableChainMode`, `PrepareMessages`), the dead `const AgentChatContextSentinelPath`, and stale chain-mode comments.
🤖 Generated by Coder Agents on behalf of @johnstcn.
|
||
|
|
b1ead5f085 |
fix: set git identity for release tagging and surface git stderr (#26945)
## What happened The [Tag and Release run](https://github.com/coder/coder/actions/runs/28549109434/job/84641825784) failed in the `prepare-release` job at the step "Prepare release (calculate version, create tag and branch)" with: ``` error: create tag v2.35.0-rc.0: exit status 128 ``` ## Root cause `prepare-release` creates an **annotated** tag via `git tag -a` (`scripts/release-action/prepare.go`), which records a tagger and therefore requires a git identity. The job never ran `git config user.name/user.email`, and runners have none configured, so git aborts with exit status 128. The real `fatal:` message was hidden because `realExecutor.RunMutation` discarded the command's stderr. ## Changes - **`.github/workflows/tag-and-release.yaml`**: add a "Configure git identity" step (`ci@coder.com` / `Coder CI`) to the `prepare-release` job, before the release tool runs. This matches the identity pattern already used later in the same workflow. - **`scripts/release-action/cmdexec.go`**: capture stderr in `RunMutation` and include it in the returned error, so a failing mutation surfaces the underlying command output (e.g. git's `fatal:` line) instead of only `exit status N`. - **`scripts/release-action/cmdexec_test.go`**: add a test asserting stderr is surfaced on failure. ## Testing - `go test ./scripts/release-action/...` passes. - `go vet ./scripts/release-action/...` and `gofmt` clean. - `actionlint .github/workflows/tag-and-release.yaml` clean. - Reproduced the failure locally: `git tag -a` with no usable identity exits 128 (`fatal: no email was given and auto-detection is disabled`); with an identity configured it succeeds. <details> <summary>Root-cause analysis / decision log</summary> **Failing step** runs `go run ./scripts/release-action prepare-release --type create-release-branch --ref main --commit cb1a87b…`. 1. The tool computes the next version `v2.35.0-rc.0` and calls `createAndPushTag`, which runs `git tag -a v2.35.0-rc.0 -m "Release v2.35.0-rc.0" <targetRef>` (`prepare.go:56`). 2. That git command exits **128**, wrapped as `error: create tag v2.35.0-rc.0: exit status 128`. **Why it's the identity, and not something else:** - No `git config user.name/user.email` step exists in the `prepare-release` job; the `setup-mise` action does not set it; and the tool itself never sets an identity. Annotated tags require a tagger, so `git tag -a` fails on runners whose auto-detected identity is bogus (`…@runner.(none)`), which is rejected under git's strict identity check. - Not a pre-existing tag collision: no `v2.35.0*` tag exists on the remote, and the code pre-checks for an existing tag (and would emit a different "already exists" error). - Not an unresolved ref: `targetRef` resolves to the provided commit SHA, checked out at `fetch-depth: 0`. - The log was unhelpful because `RunMutation` used `cmd.Run()` without wiring git's stderr (`cmdexec.go`), discarding the `fatal:` line and leaving only `exit status 128`. This PR fixes that too. - The sibling `release.yaml` explicitly sets `git config user.email/user.name` before its git mutations; that step was simply missing from the newer `tag-and-release.yaml` `prepare-release` job. </details> --- > Generated by Coder Agents on behalf of @f0ssel. |
||
|
|
ff7e0bc193 |
feat: add dry-run flag via CommandExecutor interface (#26422)
## Summary Adds a `--dry-run` capability to the `release-action` Go tool and exposes it through a **new** manual workflow, `tag-and-release.yaml`, without disturbing the existing `release.yaml` pipeline. PR #25162 had rewritten `release.yaml` in place to be driven by `scripts/release-action`, which changed its `workflow_dispatch` inputs from `release_channel`/`release_notes`/`dry_run` to `release_type`/`commit_sha`. That broke `scripts/releaser`, which dispatches `release.yaml` with the original inputs. This PR restores `release.yaml` and moves the Go-driven pipeline to its own workflow. ## Workflow layout after this PR | Workflow | Trigger | Driven by | Purpose | |---|---|---|---| | `release.yaml` | `scripts/releaser` (`gh workflow run`) | legacy inline shell | Existing pipeline, restored to pre-#25162 state | | `tag-and-release.yaml` | Manual (Actions UI) | `scripts/release-action` Go tool | New pipeline with `prepare-release` + `dry_run` | `release.yaml` is restored byte-for-byte to its pre-#25162 version, so its inputs match what `scripts/releaser` sends again. ## `release-action` design ### CommandExecutor interface Abstracts CLI command execution behind read-only and mutating methods: | Method | Purpose | Dry-run behavior | |---|---|---| | `RunOutput` | Read-only, capture stdout | Executes normally | | `Run` | Read-only, exit code only | Executes normally | | `RunMutation` | Changes remote state, no output | **Prints command, skips execution** | | `RunMutationStdout` | Changes remote state, streaming I/O | **Prints command, skips execution** | Two implementations: `realExecutor` (executes via `os/exec`) and `dryRunExecutor` (delegates read-only calls, prints mutating calls). ### `prepare-release` subcommand Composes `calculateNextVersion` with idempotent tag and branch creation+push, emitting the same JSON as `calculate-version`. Matching existing refs are skipped; mismatched refs error. ### `tag-and-release.yaml` `dry_run` input When enabled: `prepare-release` runs with `--dry-run` (version calculated, plan printed, nothing pushed), notes are generated for inspection, and the build+publish job is skipped via an `if` guard (cascading to homebrew/winget/docs). ## Mutating commands covered by `--dry-run` | Command | Call site | |---|---| | `git tag -a <version> ...` | `createAndPushTag` | | `git push origin refs/tags/...` | `createAndPushTag` | | `git push origin <sha>:refs/heads/...` | `createAndPushBranch` | | `gh release create ...` | `publishRelease` | `git fetch --tags --force origin` is intentionally not a mutation; it only updates local remote-tracking refs and must run for accurate version calculation. ## Changes - **New**: `scripts/release-action/cmdexec.go`, `prepare.go` (+ tests) - **Refactored**: `git.go`, `github.go`, `calculate.go`, `notes.go`, `commit.go`, `publish.go` to thread `CommandExecutor`; added `gitMutate` - **Updated**: `main.go` adds `--dry-run` flag and `prepare-release` subcommand - **New**: `.github/workflows/tag-and-release.yaml` (manual, Go-driven, with `dry_run`) - **Reverted**: `.github/workflows/release.yaml` to its pre-#25162 state > [!NOTE] > Generated by Coder Agents on behalf of @f0ssel |
||
|
|
608bc6e837 |
fix(scripts/oauth2): fix test-mcp-oauth2.sh for macOS and OAuth 2.1 compliance (#26825)
The `test-mcp-oauth2.sh` script had three bugs that caused tests 2, 3, and 4 to fail when run on macOS. `grep -oP` uses PCRE lookbehind (`\K`), which is not supported by BSD grep on macOS. Replaced with `grep -oE … | sed 's/code=//'` which works on both platforms. The token exchange requests in tests 2, 3, and 4 omitted `redirect_uri`, which is required by RFC 6749 §4.1.3 whenever `redirect_uri` was included in the authorization request. The server correctly rejects these with `invalid_grant`, masking the actual PKCE validation. Test 4's resource parameter flow was missing PKCE parameters entirely. The server enforces PKCE on all authorization code flows per OAuth 2.1, so the authorization request returned 400 and the script exited silently due to `set -euo pipefail`. |
||
|
|
7daf3123cb | feat: import new modules and refactor codegen script (#26838) | ||
|
|
48e8f70e09 |
fix: remove Goose module from catalog (#26833)
Removes the Goose AI agent module from the template builder backend catalog. ## Changes - Deleted `coderd/templatebuilder/modules/goose/` (Terraform template and module metadata) - Removed the `"goose"` entry from `scripts/templatebuildermodulegen/main.go` Frontend assets (`goose.svg`, `icons.json`) are intentionally left in place as other parts of the app still reference them. > Generated by Coder Agents on behalf of @jeremyruppel |
||
|
|
9f211ce5ae |
fix: use HEAD instead of fetching base branch for emdash linter (#26733)
## Problem The `lint/emdash` check fails on Graphite-stacked PRs. See [this failed run](https://github.com/coder/coder/actions/runs/28225390084/job/83616080375?pr=26650): ``` Base ref origin/graphite-base/26650 not found locally, fetching graphite-base/26650... ERROR: could not fetch base ref origin/graphite-base/26650. ERROR: could not determine base ref. make: *** [Makefile:768: lint/emdash] Error 1 ``` `scripts/check_emdash.sh` resolved its diff base by fetching `origin/$GITHUB_BASE_REF` and computing a merge-base. Graphite sets `GITHUB_BASE_REF` to a `graphite-base/<n>` ref that is ephemeral (it is not reliably present on origin), so the fetch fails and the check errors out instead of running. ## Fix `actions/checkout` checks out the PR **merge commit** (`refs/pull/<n>/merge`), whose **first parent (`HEAD^1`) is the exact base commit GitHub merged against**. Diffing `HEAD^1` against the checkout yields every change the PR makes against its base branch, for normal and Graphite-stacked PRs alike. No base-branch fetch, no merge-base computation, no `gh`-based deepen dance. - `scripts/check_emdash.sh`: use `HEAD^1` (the PR base commit) as the diff base in CI. Drops `resolve_merge_base` and `fetch_base_ref`. Emits a clear error if `HEAD^1` is missing (checkout too shallow). - `.github/workflows/ci.yaml`: bump the `lint` job checkout to `fetch-depth: 2` so `HEAD^1` is present with no runtime fetch. Local dev behavior (merge-base against `origin/main`) is unchanged. ## Verification - `make lint/emdash`, `make lint/shellcheck`, `make lint/actions/actionlint` pass. - Simulated the CI path with `GITHUB_BASE_REF` set: the check resolves to `HEAD^1` without fetching and still flags an added line containing an emdash. <details> <summary>Why the merge commit's first parent</summary> For a `pull_request` checkout of `refs/pull/<n>/merge`: - `HEAD` = GitHub's synthetic PR merge commit - `HEAD^1` = the exact base commit used for the merge - `HEAD^2` = the PR head commit `git diff HEAD^1 HEAD` is the full-tree diff from the base snapshot to the merged result, i.e. all of the PR's changes against its base. This is immutable and always local (given depth >= 2), unlike base branch refs which are mutable and, for Graphite stacks, ephemeral. </details> --- This PR was generated by Coder Agents on behalf of @dannykopping. |
||
|
|
953091c7bc |
refactor: use sync.WaitGroup.Go in tests (#26671)
Migrate `wg.Add(1); go func() { defer wg.Done(); ... }()` to
`wg.Go(func() { ... })` in tests.
Where the prior pattern passed the loop variable explicitly via a
closure parameter (`go func(id int) { ... }(i)`), drop the parameter and
reference the loop variable directly. Per-iteration loop variables since
Go 1.22 make this safe.
|
||
|
|
32217259b7 |
feat: cap tool output to fit the model context window (#26637)
## Problem
Local tool results were persisted and replayed to the model verbatim,
with no size cap. A single oversized result, most often a multi-megabyte
response from an MCP tool, overflows the prompt on the next request.
Every retry rebuilds the same history and fails the same way, leaving
the chat wedged in `error`. Auto-compaction is reactive (token usage is
only known after a response), so it can't catch a single result that
blows the very next request.
## Fix
Cap every locally-executed tool result at its single choke point,
`executeSingleTool` in `chatloop`, so the cap covers built-in tools,
**global (deployment-pinned) MCP**, **workspace MCP**, and provider
runners uniformly. Because this runs before the result is published to
the live stream and before it is committed, the SSE preview, the
persisted message, and the model replay all see the same bounded output.
The budget is token-aware: a single tool result may use at most half the
model's context window (`~4 bytes/token`), with a `16KB` floor and a
`64KB` default when the window is unknown. Truncation keeps the head and
tail of the output and replaces the middle with a marker telling the
model how much was removed and to narrow its query; it is UTF-8 safe and
never exceeds the budget. Binary media `Data` is passed through
untouched (only the text payload is bounded).
A `coderd_chatd_tool_result_truncated_total{provider,model,tool_name}`
counter and a warning log record each truncation.
## Out of scope
- Provider-executed results (e.g. web search) arrive via the stream, not
`executeSingleTool`.
- Dynamic/external tool results submitted through the `/tool-results`
API are validated as JSON elsewhere.
- Cumulative growth across many results is still handled by context
compaction; this change only bounds any single result.
<details>
<summary>Implementation notes</summary>
- New `coderd/x/chatd/chatloop/tooltruncate.go`:
`toolResultByteBudget(contextLimitTokens)` and
`truncateToolResultText(text, maxBytes)` (pure, unit-tested).
- `chatloop.go`: added `ContextLimit` to `ExecuteLocalToolsOptions`;
threaded a computed byte budget through `executeTools` into
`executeSingleTool`, where `resp.Content` is capped for the text,
media-text, and error branches.
- `generation.go`: passes `ContextLimit: prepared.ContextLimitFallback`
(the model's configured context limit).
- `metrics.go`: new `ToolResultTruncatedTotal` counter +
`RecordToolResultTruncated`.
- Tunable knobs live as constants in `tooltruncate.go`
(`toolResultContextDivisor = 2`, `bytesPerTokenEstimate`,
`minToolResultBytes`, `defaultToolResultBytes`).
Verified: `go build ./coderd/x/chatd/...`, `go test
./coderd/x/chatd/chatloop/...`, and the `chatd` test binary compiles.
</details>
---
Resolves CODAGT-678
Generated by Coder Agents on behalf of @kylecarbs.
|
||
|
|
6da322d59f | feat: add Prometheus metrics to NATS pubsub for parity with PGPubsub (#26441) | ||
|
|
a30631198d |
feat: template builder backend fixes (DEVEX-287) (#26432)
Part of the Template Builder wizard PR stack. ## Backend fixes 1. **Registry URL scheme fix**: Default `CODER_TEMPLATE_BUILDER_REGISTRY_URL` was `https://registry.coder.com` but Terraform module registry addresses must be scheme-less. Changed to `registry.coder.com`. 2. **Sensitive variable defaults**: Module `.tf.tmpl` files for claude-code, aider, amazon-q had sensitive `variable` blocks without `default`, causing `terraform plan` to fail during template import. Also fixed the `templatebuildermodulegen` script. 3. **Auto-quote string variables**: The backend now accepts raw string values from callers and wraps them in HCL quotes automatically. Previously callers were required to send pre-quoted HCL literals, which is not a reasonable API contract. --- > [!NOTE] > Generated by Coder Agents on behalf of @jeremyruppel |
||
|
|
ecfff8a7db | feat: move model settings page to ai settings | ||
|
|
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. |
||
|
|
e188ee03a4 |
fix(scripts/check_emdash.sh): skip emdash check when no diff base is available (#26489)
## Problem `scripts/check_emdash.sh` is a diff gate for pull requests: it resolves the merge-base against the target branch and only inspects added lines. When it cannot resolve a base ref, it fell back to scanning **every tracked file**. Push builds on release branches hit exactly this case: the `lint` job checks out with `fetch-depth: 1`, so `origin/main` is absent, and `GITHUB_BASE_REF` is only set for `pull_request` events. With no base ref, the whole-tree scan flags the many pre-existing emdash/endash characters already in the repo and fails `make lint` (`lint/emdash`), even though the build introduced none of them. Observed on `release/2.34` CI (run [27704528068](https://github.com/coder/coder/actions/runs/27704528068/job/81949529546)). ## Fix When no base ref can be determined (i.e. outside a pull request), skip the check instead of scanning the entire tree. A full scan remains available on demand via `scripts/check_emdash.sh --all`. ## Testing - **No base ref** (release-push simulation, no `GITHUB_BASE_REF`, no `origin/main`): old script scans all files and fails on a pre-existing emdash; new script skips and exits 0. - **PR path** (diff vs merge-base): `OK: no emdash or endash characters found.` - **`--all`**: still scans the full tree (flags pre-existing characters as before). - `shellcheck` and `shfmt` clean. ## Backports Backport PRs target `release/2.33` and `release/2.34` (same bug, older script variant). `release/2.29` and `release/2.32` do **not** contain `scripts/check_emdash.sh`, so there is nothing to backport there. <details> <summary>Decision log</summary> Considered alternatives to the skip: 1. **Compare against `github.event.before`** on push events. Rejected: the before-SHA is frequently unreachable in a `fetch-depth: 1` clone, and wiring it in requires per-workflow env changes that complicate backports. 2. **Fetch `origin/main` / deepen history** in the release lint job. Rejected for the same backport-surface reason and because it only masks the design intent. The check exists to stop *new* emdashes from landing via PRs; that gate already ran on the originating PRs. On non-PR builds there is no meaningful diff base, so skipping is correct and self-contained in the script (clean to backport). The explicit `--all` mode is preserved for intentional full-tree audits. </details> --- Generated by Coder Agents on behalf of @f0ssel. |
||
|
|
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. |
||
|
|
0040ea2efd |
chore: bump alpine from 3.23.3 to 3.24.1 in /scripts (#26406)
Bumps alpine from 3.23.3 to 3.24.1. [](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) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
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) |
||
|
|
809bd613e3 |
feat(scripts): add generator for template builder module catalog (#26193)
> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.
Adds `scripts/templatebuildermodulegen/`, a Go tool that fetches module metadata from the Coder registry HTTP API and generates the `module.json` manifests and `.tf.tmpl` files used by the template builder catalog.
The generator calls `GET /api/modules/{id}` for per-module metadata (display name, description, icon, tags, variables) and the Terraform protocol versions endpoint for semver resolution. No git clone or HCL parsing required.
Split into four files:
- `main.go`: orchestration, module config map, CLI flags
- `types.go`: output types (`ModuleManifest`, `ModuleVariable`) and API response types
- `fetch.go`: HTTP fetching, version resolution, variable conversion, icon normalization
- `write.go`: JSON writer, `.tf.tmpl` Go template and writer
|
||
|
|
a86e1ca4bb |
fix: pin Terraform 1.15.5 for all Nix platforms (#25799)
The terraform_1_15_5 derivation previously only handled linux/amd64, falling through to unstablePkgs.terraform on all other platforms. On macOS this meant a different Terraform version was used, which caused the version check in make pre-commit to trigger generate.sh, regenerating all testdata with the host platform's OS/arch (darwin/arm64) instead of the committed linux/amd64 values. Three changes: 1. `flake.nix`: add explicit linux_arm64, darwin_arm64, and darwin_amd64 cases with SHA256 hashes from the official HashiCorp release. Unknown platforms still fall back to unstablePkgs.terraform. 2. `provisioner/terraform/testdata/generate.sh`: guard full regeneration behind a Linux-only check. The committed testdata encodes linux/amd64 values from the coder_provisioner data source, so regenerating on macOS would permanently bake in darwin/arm64. The --check path still runs on all platforms so the version target can detect provider mismatches. Regeneration via CI or an explicit Linux run is unchanged. 3. `scripts/release/check_commit_metadata.sh`: fix a shfmt (>=3.13) false positive. The [install.sh] key in an associative array literal was parsed as floating-point arithmetic (a zsh-only feature). Moving it to a post-declaration assignment satisfies the stricter parser without changing runtime behavior. <!-- 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. --> Linear: DOCS-279 |
||
|
|
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 |
||
|
|
cfb03f52db |
fix: update stale docs URLs across non-TS files (#25750)
Closes [DOCS-256](https://linear.app/coder/issue/DOCS-256). Sibling to [DOCS-253](https://linear.app/coder/issue/DOCS-253) (#25740). Updates docs URL references across the non-TypeScript surface of `coder/coder` to match the current docs site structure. Source-of-truth for redirects is `coder/coder.com/redirects.json` (parent ticket [DOCS-209](https://linear.app/coder/issue/DOCS-209)). ## What changed | Area | Files | URL mapping | |---|---|---| | Top-level README | `README.md` | `/docs/workspaces` -> `/docs/user-guides/workspace-management`, `/docs/templates` -> `/docs/admin/templates`, `/docs/ides` -> `/docs/user-guides/workspace-access` | | Docs source | `docs/admin/security/0001_user_apikeys_invalidation.md` | `/docs/admin/audit-logs` -> `/docs/admin/security/audit-logs` | | Docs source | `docs/install/cloud/azure-vm.md` | `/docs/coder-oss/latest/install` -> `/docs/install` | | Dogfood | `dogfood/coder/guide.md` | `/docs/ides` -> `/docs/user-guides/workspace-access` | | Helm | `helm/coder/values.yaml` | `/docs/admin/workspace-proxies` -> `/docs/admin/networking/workspace-proxies` | | Enterprise coderd | `enterprise/coderd/coderd.go` | `/docs/admin/encryption` -> `/docs/admin/security/database-encryption` (error message) | | Release tooling | `scripts/release/main_internal_test.go` | `/docs/admin/upgrade` -> `/docs/install/upgrade` (test fixture, matches `generate_release_notes.sh`) | | AI bridge | `aibridge/client.go` | repinned to current `main` SHA on renamed `docs/ai-coder/ai-gateway/monitoring.md`, line range `#L47-L57` | | Example templates | 12 `examples/templates/*/README.md`, `examples/parameters/*`, `examples/parameters-dynamic-options/README.md`, `examples/workspace-tags/README.md`, `examples/parameters/main.tf`, `examples/examples.gen.json` (regenerated) | `/docs/workspaces` -> `/docs/user-guides/workspace-management`, `/docs/templates/parameters` -> `/docs/admin/templates/extending-templates/parameters`, `/docs/templates/dev-containers` -> `/docs/admin/integrations/devcontainers`, `/docs/dotfiles` -> `/docs/user-guides/workspace-dotfiles`, `/docs/about/architecture#agents` -> `/docs/admin/infrastructure/architecture#agents` | | Live notification templates (DB) | New migration `000510_fix_dormancy_notification_docs_urls.up.sql` and `.down.sql` plus the four regenerated SMTP/webhook goldens under `coderd/notifications/testdata/rendered-templates/` | `/docs/templates/schedule#dormancy-threshold-enterprise` -> `/docs/admin/templates/managing-templates/schedule#dormancy-threshold`, `/docs/templates/schedule#dormancy-auto-deletion-enterprise` -> `/docs/admin/templates/managing-templates/schedule#dormancy-auto-deletion` | The migration uses `REPLACE(body_template, ...)` scoped by template id and `LIKE '%/docs/templates/schedule%'`, so it works regardless of which intermediate state (`000232`, `000262`, `000305`, or `000311`) is currently in the row. ## What did not change Historical SQL migrations `000232`, `000262`, `000305`, and `000311` are not modified because migrations are immutable history. The 18 remaining stale URL references in those files are superseded at runtime by migration `000510`. This decision matches the pattern used in the A1 sister PR (#25740). ## Verification - `go test ./coderd/database/migrations/... -count=1` (UP+DOWN) - `go test ./coderd/notifications/ -run TestNotificationTemplates_Golden -update -count=1` to regenerate the four `.golden` files - `go test ./scripts/release/ -run Test_removeMainlineBlurb -count=1` - `make pre-commit` (gen + fmt + lint + slim build) ran clean as part of the commit hook I also fixed a pre-existing emdash on line 35 of `examples/templates/azure-linux/README.md` that the lint flagged once the file entered my diff. The line was already in `main`, but `make gen` rewrites `examples/examples.gen.json` whenever a `README.md` changes, so the line came back as a `+` in the diff against `origin/main` and the `lint/emdash` step refused it. <details> <summary>Pre-mortem</summary> | Risk | Mitigation | |---|---| | Migration overwrites future template edits | Used `REPLACE` instead of full body overwrite. `WHERE id IN (...) AND body_template LIKE '%/docs/templates/schedule%'` further scopes the write | | Goldens drift from migrated body | Regenerated goldens via `-update` after the migration was in place, so the goldens reflect the post-migration state | | Down migration leaves stale URLs | Down migration reverses the REPLACE so a rollback restores the prior URLs | | Fragment loss when redirect strips fragment | Verified the destination `schedule.md` contains `## Dormancy threshold` and `## Dormancy auto-deletion` anchors | | Terraform parse breakage in `examples/parameters/main.tf` | Only comments changed; Terraform parser is unaffected | | Test fixtures in `scripts/release` diverging from `generate_release_notes.sh` | Updated to match the script, which already emits `/docs/install/upgrade` | </details> --- Generated by Coder Agent on behalf of @nickvigilante. |
||
|
|
4627b01415 |
fix: reduce agentfake manager startup time (#25669)
Signed-off-by: Callum Styan <callumstyan@gmail.com> Co-authored-by: Mux <noreply@coder.com> |
||
|
|
b95697a370 |
ci: rewrite release workflow to be fully GitHub Actions-driven (#25162)
Replace the local interactive release CLI and legacy shell scripts with a non-interactive Go tool (`scripts/release-action/`) and a rewritten `release.yaml` workflow. Release managers trigger releases from the GitHub Actions UI by selecting a branch, picking a release type (`rc`, `release`, or `create-release-branch`), and optionally providing a commit SHA. The Go tool has four subcommands: `calculate-version` (computes next version from git state), `generate-notes` (release notes from commit log and PR metadata), `publish` (creates GitHub release with checksums), and the workflow handles tag creation, branch creation, building, and downstream publishing. `scripts/version.sh` fallback now uses `git describe` (nearest ancestor tag) instead of global latest so dev builds on release branches show the correct version series. |
||
|
|
2cbce86eee |
chore: update install docs for v2.34.0 release (#26058)
Updates the install docs for the v2.34.0 release, branched off the latest `main`. Supersedes #25995: same release-docs update, but cut from current `main` and with every "Latest Release" link refreshed. The automated PR carried stale patch links and a `vv2.34.0` typo. ## Changes - `docs/install/releases/index.md`: regenerate the release calendar. 2.34 → Mainline, 2.33 → Stable, and every "Latest Release" link points to the current patch per minor (`2.24.6, 2.29.16, 2.30.9, 2.31.14, 2.32.5, 2.33.6, 2.34.0`). - `docs/install/rancher.md`: version selector → Mainline `2.34.0`, Stable `2.33.6`. - `docs/install/kubernetes.md`: Helm `--version` → Mainline `2.34.0`, Stable `2.33.6` (chart + OCI), matching the Rancher guide. Addresses the review feedback on #25995: the `vv2.34.0` typo, bumping Stable to `2.33.6`, and keeping the Kubernetes guide in sync with Rancher. <details> <summary>Notes for reviewers</summary> - Verified with `markdownlint-cli2` (0 errors) and `markdown-table-formatter --check` (no reformatting needed). - The calendar was regenerated via `scripts/update-release-calendar.sh`. That script's `get_latest_patch` does not exclude prerelease tags, so it selected `v2.34.0-rc.0` over `v2.34.0`; that row was corrected by hand. A follow-up fix to the script would prevent this recurring. - The linkspector 404 on `coder.com/changelog/coder-2-34` is expected for a fresh release; that page publishes alongside the release. </details> --- *Generated by Coder Agents on behalf of @f0ssel.* |
||
|
|
8b058dc949 |
feat: add coderd_api_websocket_probes_total metric (#25012)
Relates to CODAGT-115 Adds metric `coderd_api_websocket_probes_total`. Every successful heartbeat for a given path will increment the metric. Comparing this with `coderd_api_concurrent_websockets` will give an indication of how many websocket connections are open but in a 'wedged' state (when heartbeats stopped versus when we closed the connection). |
||
|
|
fe257666d7 | ci: refactor CI to use mise for shared tool setup (#25727) | ||
|
|
9c111a2be2 | chore: disable release freezing on dev.coder.com (#25881) | ||
|
|
12520ee964 |
feat: add ai provider status and reload freshness metrics (#25770)
Add metrics for `aibridged` and `aibridgeproxyd`'s provider statuses. AI providers can be modified, and possibly misconfigured, at runtime. These metrics help operators understand the state of these provider definitions in case unexpected behaviour is observed. |
||
|
|
3770176b7f |
fix(scripts): use merge-base in emdash lint to avoid false positives (#25726)
When GITHUB_BASE_REF is set, the emdash lint compared against the tip of main instead of the merge-base. For PRs behind main, this produced a diff covering all divergent files, flagging pre-existing emdashes the PR never touched. Query the PR commit count via gh, deepen HEAD by that amount, and resolve HEAD~N as the merge-base. Falls back to the branch tip when the merge-base cannot be determined. |
||
|
|
1bfc1ce2c4 |
chore: update terraform to v1.15.5 (#25746)
Bumps bundled Terraform from `1.15.2` to `1.15.5` across all pinned locations: - `.github/actions/setup-tf/action.yaml` - `scripts/Dockerfile.base` - `install.sh` - `flake.nix` (+ updated SRI hash for the linux_amd64 zip) - `mise.toml` - `mise.lock` (+ updated per-platform SHA256 checksums) - `provisioner/terraform/testdata/version.txt` - `provisioner/terraform/testdata/resources/ai-tasks-disabled/ai-tasks-disabled.tfplan.json` ## Why Terraform 1.15.5 is built with Go 1.25.10, while the 1.15.2 we currently ship was built with Go 1.25.8. The newer Go runtime addresses recent stdlib CVEs flagged by security scanners. Releases included: 1.15.3 (provider install crash fix, nested-module stack migration fix), 1.15.4 (Linux s390x builds, symlinked provider dir fix), 1.15.5. Release notes: https://github.com/hashicorp/terraform/releases/tag/v1.15.5 ## Cherry-pick #25747 mirrors this PR against `release/2.34`. Created on behalf of @Shelnutt2 Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> |
||
|
|
51836e681e |
refactor: build dogfood image as base + mise oci layers (#25448)
Splits the dogfood image into two artifacts: - `ghcr.io/coder/oss-dogfood-base:<distro>-<base-sha>`: Ubuntu base with apt packages, chrome, rustup, brew, gh, and the mise binary. The base-sha is a cache key over `Dockerfile.base` and `files/`, so commits that don't touch those inputs reuse the previous build. - `codercom/oss-dogfood:<final-sha>-<distro>` and rolling tags (`:22.04`, `:26.04`, `:latest`, `:<branch>`): produced by `mise oci build` on top of the base, with one content-addressed OCI layer per mise tool. The rolling tag scheme is unchanged, so the workspace template doesn't need updating. Single-tool version bumps now invalidate only that tool's OCI layer, so workspaces re-pull just what changed instead of the entire 5-6 GB image on every recreate. Also: - Drops the build-time `pnpm dlx playwright@1.47.0 install --with-deps chromium` step (~400 MB) and the equivalent `playwright-driver.browsers` install from `flake.nix`. `@playwright/mcp` (used by the claude-code and codex MCP servers in `dogfood/coder/main.tf`) does NOT auto-install browsers, so the existing `install-deps` `coder_script` now runs two installs on workspace start: `pnpm exec playwright install chromium` for the site's pinned `@playwright/test`, and `npx --package=@playwright/mcp@latest playwright-core install --no-shell chromium` so the MCP servers find their matching browser revision. Browser revisions coexist under `~/.cache/ms-playwright/chromium-<rev>/`, which lives on the home volume so both downloads happen once per workspace recreate and persist across restarts. Net effect: same MCP behavior as before, +~1-2 min on first workspace start. Nix devshell users running site e2e tests locally now need `pnpm exec playwright install` once (instead of getting browsers via nixpkgs). - Bumps the pinned mise binary to v2026.5.12 (matching main after #25521) and adds top-level `min_version = "2026.5.12"` to `mise.toml` so every consumer (devs, CI, the embedded mise inside the dogfood image, mise oci builds) fails fast on an older mise. - Adds bison, flex, libicu-dev, libreadline-dev, uuid-dev, and zlib1g-dev to both Ubuntu base images for source-build use cases (e.g., building Postgres from source). - Replaces skopeo with crane as the registry client `mise oci push` shells out to: crane is added to `mise.toml`, the workflow drops its `apt-get install skopeo` and forces `--tool crane`, and the local wrapper image stops bundling skopeo. One source of truth for tool versions, no apt drift, smaller wrapper image, and workspace users get a registry client on PATH for free via mise oci's tool layers. - Removes `nix.hash`/`mise.hash` and their Makefile rules. The registry digest already captures every effective change since CI rebuilds when any baked-in input moves; the per-file `filesha1()` entries in `pull_triggers` are redundant. Supersedes #25400 (the `mise.hash` pull trigger landed there in `2b612abe7b`; this PR removes it as part of the broader simplification). > [!NOTE] > `mise oci build` is experimental and requires `MISE_EXPERIMENTAL=1` (set at job level in the workflow). The local-only `scripts/dogfood/mise-oci-wrapper.sh` builds a tiny `coderdev/mise-oci-wrapper:<version>` Debian image with curl-installed mise on first invocation (cached by version tag thereafter); we don't reuse `jdxcode/mise:latest` because that tag lags upstream GitHub releases by days and would defeat the `min_version` enforcement above. > [!NOTE] > `compute-base-sha.sh` and `compute-final-sha.sh` are cache keys, not strict content addresses: the base Dockerfile still pulls dynamic resources at build time (gh/buildx `releases/latest`, chrome `stable_current_amd64.deb`, apt mirror state). Two runs with identical checked-in files can produce slightly different bytes, which is acceptable here because the cache-hit savings on irrelevant commits outweigh that drift. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Thomas Kosiewski <tk@coder.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
0a45f96d30 |
ci: validate dogfood image tooling by running gen, fmt, lint, build (#25475)
Adds a `test_image` job that runs `make gen`, `make fmt`, `make lint`, and `make build` inside the newly built image via `docker run`. This helps detect breaking changes before merge. > [!NOTE] > Generated with [Coder Agents](https://coder.com/agents) |
||
|
|
a4afb9dfc6 |
feat: add --env-file flag to develop.sh (#25621)
Adds `--env-file` to `scripts/develop.sh` to allow reading environment from a given file. This makes it easier to configure things like external auth providers, access URLs, and other dev-time settings without exporting a wall of environment variables in every shell session. > Generated with [Coder Agents](https://coder.com/agents) |