mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
a130a7dc97ef121aadbc1bf58cffc87f7120f144
13010
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d6306461bb |
feat(site): render computer tool screenshots as images in chat UI (#23074)
Instead of showing raw base64 JSON for Anthropic's computer use tool, render the screenshot as an inline image. The image is clickable to open at full resolution in a new tab. ## Changes - **ComputerTool.tsx** — New component that renders base64 image data as an `<img>` tag - **Tool.tsx** — Added `ComputerRenderer` handling both single-object and array-of-blocks result shapes - **ToolIcon.tsx** — Added `MonitorIcon` for the `computer` tool - **ToolLabel.tsx** — Added \Screenshot\ label for the `computer` tool |
||
|
|
cb05419872 | fix(site): inject time via prop for deterministic analytics story snapshots (#23092) | ||
|
|
29225252f6 |
chore: bump google.golang.org/api from 0.269.0 to 0.271.0 (#23102)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.269.0 to 0.271.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's releases</a>.</em></p> <blockquote> <h2>v0.271.0</h2> <h2><a href="https://github.com/googleapis/google-api-go-client/compare/v0.270.0...v0.271.0">0.271.0</a> (2026-03-10)</h2> <h3>Features</h3> <ul> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3532">#3532</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ccff5b35c0d730214473de122dcb96b110be0029">ccff5b3</a>)</li> </ul> <h2>v0.270.0</h2> <h2><a href="https://github.com/googleapis/google-api-go-client/compare/v0.269.0...v0.270.0">0.270.0</a> (2026-03-08)</h2> <h3>Features</h3> <ul> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3515">#3515</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/44db8ef7d07171dad68a5cc9026ab3f1cd77ef12">44db8ef</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3518">#3518</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b3dc663d78cba7be5dbd998a439edcdf4991b807">b3dc663</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3519">#3519</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/01c06b9034963e27855bf188049d1752fc2de525">01c06b9</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3520">#3520</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/7ed04540e547ca9cef1f9f48d54c1277f24773bf">7ed0454</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3521">#3521</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/d11f54e813163dfc52515d214065c67bc944c7ef">d11f54e</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3523">#3523</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ce39b40dedcd239ea2fb4a18aedf23ba61b8ae90">ce39b40</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3525">#3525</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/15b140d66a7b67dd6bfea7d1473bd2df4d878f95">15b140d</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3526">#3526</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/1b18158bb7807b1a5a9f73dd4ec450f274a81da8">1b18158</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3527">#3527</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/a932a454c4fd97dfc66f0cca97afeae231a7e4e9">a932a45</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3528">#3528</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/f6ede69e7094cf4f7353841d593867f087f06b84">f6ede69</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3529">#3529</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b73e4fbc0017249279922cb4c223e44f98cc5db9">b73e4fb</a>)</li> <li><strong>option/internaloption:</strong> Add more option introspection (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3524">#3524</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ac5da8f06619417a42c5e128dcb5aafcb1912353">ac5da8f</a>)</li> <li><strong>option/internaloption:</strong> Unsafe option resolver (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3514">#3514</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b263ceeb1a4062ae6cda17c49073d5051d96fc90">b263cee</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/googleapis/google-api-go-client/compare/v0.270.0...v0.271.0">0.271.0</a> (2026-03-10)</h2> <h3>Features</h3> <ul> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3532">#3532</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ccff5b35c0d730214473de122dcb96b110be0029">ccff5b3</a>)</li> </ul> <h2><a href="https://github.com/googleapis/google-api-go-client/compare/v0.269.0...v0.270.0">0.270.0</a> (2026-03-08)</h2> <h3>Features</h3> <ul> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3515">#3515</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/44db8ef7d07171dad68a5cc9026ab3f1cd77ef12">44db8ef</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3518">#3518</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b3dc663d78cba7be5dbd998a439edcdf4991b807">b3dc663</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3519">#3519</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/01c06b9034963e27855bf188049d1752fc2de525">01c06b9</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3520">#3520</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/7ed04540e547ca9cef1f9f48d54c1277f24773bf">7ed0454</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3521">#3521</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/d11f54e813163dfc52515d214065c67bc944c7ef">d11f54e</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3523">#3523</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ce39b40dedcd239ea2fb4a18aedf23ba61b8ae90">ce39b40</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3525">#3525</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/15b140d66a7b67dd6bfea7d1473bd2df4d878f95">15b140d</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3526">#3526</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/1b18158bb7807b1a5a9f73dd4ec450f274a81da8">1b18158</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3527">#3527</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/a932a454c4fd97dfc66f0cca97afeae231a7e4e9">a932a45</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3528">#3528</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/f6ede69e7094cf4f7353841d593867f087f06b84">f6ede69</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3529">#3529</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b73e4fbc0017249279922cb4c223e44f98cc5db9">b73e4fb</a>)</li> <li><strong>option/internaloption:</strong> Add more option introspection (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3524">#3524</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/ac5da8f06619417a42c5e128dcb5aafcb1912353">ac5da8f</a>)</li> <li><strong>option/internaloption:</strong> Unsafe option resolver (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3514">#3514</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/b263ceeb1a4062ae6cda17c49073d5051d96fc90">b263cee</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/googleapis/google-api-go-client/commit/e79327bd305ea52af1334ef6b5385cf7a5acbbdc"><code>e79327b</code></a> chore(main): release 0.271.0 (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3533">#3533</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/a3dde28f12bc0c1aaab4a8a74ad9f46b53d53004"><code>a3dde28</code></a> chore(deps): bump github.com/cloudflare/circl from 1.6.1 to 1.6.3 in /interna...</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/bad57c0a2c19b7e0e5f5083d911544cca340a98a"><code>bad57c0</code></a> chore(all): update all (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3530">#3530</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/ccff5b35c0d730214473de122dcb96b110be0029"><code>ccff5b3</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3532">#3532</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/15dd0b11d31423e7811736bbabe7e512a214f225"><code>15dd0b1</code></a> chore(option/internaloption): more accessors (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3531">#3531</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/ad5d5aa8fa892f0129604d9c139081cc99eb4700"><code>ad5d5aa</code></a> chore(main): release 0.270.0 (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3516">#3516</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/b73e4fbc0017249279922cb4c223e44f98cc5db9"><code>b73e4fb</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3529">#3529</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/f6ede69e7094cf4f7353841d593867f087f06b84"><code>f6ede69</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3528">#3528</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/7342fc24a37cfa818cf4834578e0198c1b5e0334"><code>7342fc2</code></a> chore(all): update all (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3522">#3522</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/a932a454c4fd97dfc66f0cca97afeae231a7e4e9"><code>a932a45</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3527">#3527</a>)</li> <li>Additional commits viewable in <a href="https://github.com/googleapis/google-api-go-client/compare/v0.269.0...v0.271.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
93ea5f5d22 |
chore: bump github.com/coder/terraform-provider-coder/v2 from 2.13.1 to 2.14.0 (#23101)
Bumps [github.com/coder/terraform-provider-coder/v2](https://github.com/coder/terraform-provider-coder) from 2.13.1 to 2.14.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/coder/terraform-provider-coder/releases">github.com/coder/terraform-provider-coder/v2's releases</a>.</em></p> <blockquote> <h2>v2.14.0</h2> <h2>What's Changed</h2> <ul> <li>build(deps): Bump golang.org/x/mod from 0.29.0 to 0.30.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/463">coder/terraform-provider-coder#463</a></li> <li>build(deps): Bump actions/checkout from 5 to 6 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/468">coder/terraform-provider-coder#468</a></li> <li>build(deps): Bump golang.org/x/crypto from 0.43.0 to 0.45.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/467">coder/terraform-provider-coder#467</a></li> <li>build(deps): Bump github.com/hashicorp/terraform-plugin-log from 0.9.0 to 0.10.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/465">coder/terraform-provider-coder#465</a></li> <li>fix: typo in data coder_external_auth example and docs by <a href="https://github.com/krispage"><code>@krispage</code></a> in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/420">coder/terraform-provider-coder#420</a></li> <li>feat: add confliction with <code>subdomain</code> by <a href="https://github.com/jakehwll"><code>@jakehwll</code></a> in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/469">coder/terraform-provider-coder#469</a></li> <li>build(deps): Bump golang.org/x/mod from 0.30.0 to 0.31.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/472">coder/terraform-provider-coder#472</a></li> <li>build(deps): Bump golang.org/x/mod from 0.31.0 to 0.32.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/473">coder/terraform-provider-coder#473</a></li> <li>feat: add <code>subagent_id</code> attribute to <code>coder_devcontainer</code> resource by <a href="https://github.com/DanielleMaywood"><code>@DanielleMaywood</code></a> in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/474">coder/terraform-provider-coder#474</a></li> <li>fix: embed timezone database via <code>time/tzdata</code> by <a href="https://github.com/mtojek"><code>@mtojek</code></a> in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/476">coder/terraform-provider-coder#476</a></li> <li>build(deps): Bump golang.org/x/mod from 0.32.0 to 0.33.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/477">coder/terraform-provider-coder#477</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/krispage"><code>@krispage</code></a> made their first contribution in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/420">coder/terraform-provider-coder#420</a></li> <li><a href="https://github.com/jakehwll"><code>@jakehwll</code></a> made their first contribution in <a href="https://redirect.github.com/coder/terraform-provider-coder/pull/469">coder/terraform-provider-coder#469</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/coder/terraform-provider-coder/compare/v2.13.1...v2.14.0">https://github.com/coder/terraform-provider-coder/compare/v2.13.1...v2.14.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/coder/terraform-provider-coder/commit/7fa3c10eaaf66dd1f67a14176a438cf05ec9e98e"><code>7fa3c10</code></a> build(deps): Bump golang.org/x/mod from 0.32.0 to 0.33.0 (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/477">#477</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/ef9a6dda578892cdcf7ab7cf920a732010b86151"><code>ef9a6dd</code></a> fix: embed timezone database via <code>time/tzdata</code> (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/476">#476</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/b6966bf427c6d9d418dd6a217fe8897bc15f618c"><code>b6966bf</code></a> feat: add <code>subagent_id</code> attribute to <code>coder_devcontainer</code> resource (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/474">#474</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/c9f205fca1ca25c70704be555ff524a46dff9f2e"><code>c9f205f</code></a> build(deps): Bump golang.org/x/mod from 0.31.0 to 0.32.0 (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/473">#473</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/7a81d185379885b6b30a96a40fd8e5f7eee2640c"><code>7a81d18</code></a> build(deps): Bump golang.org/x/mod from 0.30.0 to 0.31.0 (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/472">#472</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/76bda72ec5f47be88edd6d0c1347802609b1d041"><code>76bda72</code></a> feat: add confliction with <code>subdomain</code> (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/469">#469</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/aee79c41a4e4f6770db90291dffe01c53667d8dc"><code>aee79c4</code></a> fix: typo in data coder_external_auth example and docs (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/420">#420</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/9cfd35f441fa567150ecd5aa97c5f854a2800182"><code>9cfd35f</code></a> build(deps): Bump github.com/hashicorp/terraform-plugin-log (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/465">#465</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/dd6246532b4f0047c0125bdcd70f6e900ca69d65"><code>dd62465</code></a> build(deps): Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/467">#467</a>)</li> <li><a href="https://github.com/coder/terraform-provider-coder/commit/60377bb12b7593f11f23a986e8a386d5566a0718"><code>60377bb</code></a> build(deps): Bump actions/checkout from 5 to 6 (<a href="https://redirect.github.com/coder/terraform-provider-coder/issues/468">#468</a>)</li> <li>Additional commits viewable in <a href="https://github.com/coder/terraform-provider-coder/compare/v2.13.1...v2.14.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
9a6356513b |
chore: bump rust from d6782f2 to 7d37016 in /dogfood/coder (#23103)
Bumps rust from `d6782f2` to `7d37016`. [](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> |
||
|
|
069d3e2beb |
fix(coderd): require ssh access for workspace chats (#23094)
### Motivation - The chat creation flow associated a workspace agent for a chat if the requester could read the workspace, enabling privilege escalation where users without SSH/app-connect permissions could cause the daemon to open privileged agent connections and execute commands. - The intent is to ensure that attaching a workspace agent to a chat only happens when the requester has the workspace SSH permission so the chat daemon cannot be abused to bypass RBAC. ### Description - Require request-scoped authorization for workspace agent usage by changing `validateCreateChatWorkspaceSelection` to accept the `*http.Request` and calling `api.Authorize(r, policy.ActionSSH, workspace)` before selecting the workspace for a chat. - Pass the HTTP request into the validator from `postChats` so authorization is evaluated in the request context (`postChats` now calls `validateCreateChatWorkspaceSelection(ctx, r, req)`). - Add a regression test `WorkspaceAccessibleButNoSSH` in `coderd/chats_test.go` which creates an org-admin-scoped user (read access but no `ActionSSH`) and asserts that creating a chat with `WorkspaceID` is denied. ### Testing - Ran `gofmt -w coderd/chats.go coderd/chats_test.go` which succeeded. - Attempted to run repository pre-commit checks (`make pre-commit`) and targeted `go test` invocations; these checks could not be completed in this environment due to missing local tooling and environment constraints (protobuf include resolution, containerized DB access via Docker socket, and long-running golden generation tasks), so full CI/pre-commit verification and end-to-end test runs did not complete here. - Added a focused regression unit test (`WorkspaceAccessibleButNoSSH`) to prevent reintroduction of the authorization bypass; this test is included in the change and should be executed in CI where the full toolchain and test environment are available. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_b_69b432502670832e91d14e937745de46) |
||
|
|
aa6f301305 |
ci: add conventional commit PR title linting (#23096)
Restore PR title validation that was removed in
|
||
|
|
ae8bed4d8e |
feat(site): improve DERP health page readability (#22984)
## Why The DERP health page displayed raw field names like `MappingVariesByDestIP`, `PMP`, `PCP`, `HairPinning` with no context. Users without deep networking knowledge had no way to understand what these flags meant or why they mattered. This change makes the page self-documenting. ## What - DERPPage (`/health/derp`) - Replace flat pill row with four logically grouped tables: **Connectivity**, **IPv6 Support**, **NAT Traversal**, **Port Mapping**. - Rename section from "Flags" to "Network Checks". - Surface `CaptivePortal` flag (previously missing from the UI entirely). - Invert display of `MappingVariesByDestIP` and `CaptivePortal` so green always means good. - Handle `null` boolean fields (e.g. UPnP, PMP, PCP) with a distinct "not checked" neutral icon. - DERPRegionPage (`/health/derp/regions/:regionId`) - Replace per-node `BooleanPill` row with a table showing **Exchange Messages**, **Direct HTTP Upgrade**, **STUN Enabled**, and **STUN Reachable** per node. - Invert `uses_websocket` display as "Direct HTTP Upgrade" (green when websocket is not needed). - Surface **STUN Enabled** and **STUN Reachable** per node (data was returned by the API but never rendered). - Add null guards for `region` and `node` (remove `!` non-null assertions). - Convert all emotion/MUI styles to Tailwind classes; remove `reportStyles` object and `useTheme` import. - Content.tsx (shared) - Adds an exported `StatusIcon` component with three states: `true` (green check), `false` (red minus), `null` (neutral help icon). |
||
|
|
703b974757 |
fix(coderd): remove false devcontainers early access warning (#23056)
The script source claimed Dev Containers are early access and told users to set CODER_AGENT_DEVCONTAINERS_ENABLE=true, which already defaults to true. Clear the script source and set RunOnStart to false since there is nothing to run. |
||
|
|
9c2f217ca2 |
chore: bump the coder-modules group across 3 directories with 2 updates (#23091)
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 <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
3d9628c27e |
ci: split build artifacts into per-platform uploads (#23081)
Splits the single `coder` artifact (containing all platforms in a 1.3GB zip) into individual artifacts per OS/arch/format. ## Problem All CI build artifacts are uploaded as a single artifact named `coder`, producing a 1.3GB zip containing every platform's binary. This makes it impossible to download a single platform's binary without pulling the entire bundle. ## Solution Upload each platform/format combination as a separate artifact: | Artifact Name | Contents | |---|---| | `coder-linux-amd64.tar.gz` | Linux amd64 tarball | | `coder-linux-amd64.deb` | Linux amd64 deb package | | `coder-linux-arm64.tar.gz` | Linux arm64 tarball | | `coder-linux-arm64.deb` | Linux arm64 deb package | | `coder-linux-armv7.tar.gz` | Linux armv7 tarball | | `coder-linux-armv7.deb` | Linux armv7 deb package | | `coder-windows-amd64.zip` | Windows amd64 zip | ## Plan This is the first step toward letting customers install directly from `main` via: ```bash curl -L https://coder.com/install.sh | sh -s -- --unsafe-unstable ``` GitHub Actions artifact downloads require authentication even for public repos, so the next steps are to add a small Cloudflare Worker (similar to the one we already have for `install.sh`) that: 1. Lists artifacts via the GitHub API (unauthenticated) to find the latest artifact ID for the requested platform 2. Calls the download endpoint with a GitHub token (CF Worker secret) to get a 302 redirect to a time-limited Azure Blob URL 3. Redirects the caller to that URL (which requires no auth) This gives us publicly accessible per-platform URLs that the `--unsafe-unstable` flag would point at. The worker doesn't proxy the binary itself — it only proxies the metadata API call (~1KB) and redirects for the actual download. This PR splits the artifacts so the worker can serve individual platform downloads (~200MB each) instead of forcing a 1.3GB bundle. |
||
|
|
a2b8564c48 | chore: update deploy to use EKS (#23084) | ||
|
|
1adc22fffd |
fix(agent/reaper): skip reaper tests in CI (#23068)
ForkReap's syscall.ForkExec and process-directed signals remain flaky in CI despite the subprocess isolation added in #22894. Restore the testutil.InCI() skip guard that was removed in that change. Fixes coder/internal#1402 |
||
|
|
266c611716 |
refactor(site): consolidate Git panel diff viewers and polish UI (#23080)
## Summary Refactors the Git panel in the Agents page to consolidate duplicated diff viewer code and significantly improve the UI. ### Deduplication - **RemoteDiffPanel** now uses the shared `DiffViewer` component instead of duplicating file tree, lazy loading, scroll tracking, and layout (~500 lines removed). - Renamed `RepoChangesPanel` → `LocalDiffPanel`, `FilesChangedPanel` → `RemoteDiffPanel` to reflect actual scope. - Removed `headerLeft`/`headerRight` abstraction from `DiffViewer` — each consumer owns its own header. - Replaced hand-rolled `ChatDiffStatusResponse` with auto-generated `ChatDiffStatus` from `typesGenerated.ts`. ### Tab Redesign - Per-repo tabs: each local repo gets its own tab (`Working <repo>`) instead of a single stacked view. - PR tab shows state icon + PR title; branch-only tab shows branch icon. - Tabs use `Button variant="outline"` matching the Git/Desktop tab style. - Radix `ScrollArea` with thin horizontal scrollbar for tab overflow. - Diff style toggle and refresh button lifted to shared toolbar, always visible. ### PR Header - Compact sub-header: `base_branch ←`, state badge (`Open`/`Draft`/`Merged`/`Closed`), diff stats, and `View PR` button. - GitHub-style state-aware icons (green open, gray draft, purple merged, red closed). - New API fields synced: `base_branch`, `author_login`, `pr_number`, `commits`, `approved`, `reviewer_count`. ### Local Changes Header - Compact sub-header: branch name, repo root path, diff stats, and `Commit` button (styled to match `View PR`). - `CircleDotIcon` (amber) for working changes tabs — universal "modified" indicator. ### Visual Polish - All text in sub-headers and buttons at 13px matching chat font size. - All badges (`DiffStatBadge`, PR state, `View PR`, `Commit`) use consistent `border-border-default`, `rounded-sm`, `leading-5`. - No background color on diff viewer header bars. - Tabs hidden when their view has no content; auto-switch when active tab disappears. ### Stories - New `GitPanel.stories.tsx` covering: open PR + working changes, draft PR, merged PR, closed PR, branch only, working changes only, multiple repos, empty state. - Removed old `LocalDiffPanel.stories.tsx` and `RemoteDiffPanel.stories.tsx`. |
||
|
|
83e4f9f93e |
fix(agents): narrow chat mutation query invalidation (#23078)
## Problem
Sending a message on the `/agents` page triggers a burst of redundant
HTTP requests. The root cause is that chat mutations call
`invalidateQueries({ queryKey: ["chats"] })` which, due to React Query's
default **prefix matching**, cascades to every query whose key starts
with `["chats"]`:
- `["chats", {archived: false}]` — infinite sidebar list
- `["chats", chatId]` — individual chat detail
- `["chats", chatId, "messages"]` — all messages
- `["chats", chatId, "diff-status"]` — diff status
- `["chats", chatId, "diff-contents"]` — diff contents
- `["chats", "costSummary", ...]` — cost summaries
All of these have active subscribers on the page, so each one fires a
network request. The WebSocket stream already delivers these updates in
real-time, making the HTTP refetches completely redundant.
## Fix
| Mutation | Before | After |
|---|---|---|
| `createChatMessage` | `invalidateQueries({ queryKey: chatsKey })` —
prefix cascade | **Removed** — WebSocket delivers messages + sidebar
updates |
| `interruptChat` | `invalidateQueries({ queryKey: chatsKey })` — prefix
cascade | **Removed** — WebSocket delivers status changes |
| `editChatMessage` | 3 broad invalidations including `chatsKey` prefix
| 2 targeted with `exact: true`: `chatKey(id)` + `chatMessagesKey(id)` |
| `promoteChatQueuedMessage` | 3 broad invalidations including
`chatsKey` prefix | 2 targeted with `exact: true`: `chatKey(id)` +
`chatMessagesKey(id)` |
`editChatMessage` keeps `chatMessagesKey` invalidation because editing
truncates messages server-side and the WebSocket can only insert/update,
never remove stale entries.
## Net effect
Sending a message previously triggered **5–7 HTTP requests**. Now it
triggers **zero** — the WebSocket handles everything.
## Tests
Added `describe("mutation invalidation scope")` with 8 test cases
asserting that each mutation only invalidates the queries it genuinely
needs.
|
||
|
|
ff9d061ae9 |
fix(site): prevent duplicate chat in agents sidebar on creation (#23077)
## Problem
When creating a new chat in the agents page (`/agents`), the chat could
appear multiple times in the sidebar. This was a race condition
triggered by the WebSocket `created` event handler.
## Root Cause
`updateInfiniteChatsCache` applies its updater function **independently
on each page** of the infinite query:
```ts
const nextPages = prev.pages.map((page) => updater(page));
```
When the `watchChats` WebSocket received a `"created"` event, the
handler checked `exists` only within the *current page*, then prepended
the new chat if not found:
```ts
updateInfiniteChatsCache(queryClient, (chats) => {
const exists = chats.some((c) => c.id === updatedChat.id);
// ...
if (chatEvent.kind === "created") {
return [updatedChat, ...chats]; // runs per page!
}
});
```
Since a brand-new chat doesn't exist in any page, **every loaded page**
prepends it. After `pages.flat()`, the chat appears once per loaded page
in the sidebar.
## Fix
- Added `prependToInfiniteChatsCache` in `chats.ts` that checks across
**all pages** before prepending, and only adds to page 0.
- Split the WebSocket handler so `"created"` events use the new safe
prepend, while update events (`title_change`, `status_change`) continue
using `updateInfiniteChatsCache` (which is safe for `.map()` operations
that don't add entries).
|
||
|
|
0d3e39a24e |
feat: add head_branch to pull request diff status (#23076)
Adds the `head_branch` field (the source/feature branch name of a PR) to the diff status pipeline. Previously only `base_branch` (target branch) and the head commit SHA were captured from the GitHub API, but not the head branch name itself. ## Changes - **Migration 438**: Add `head_branch` nullable TEXT column to `chat_diff_statuses` - **gitprovider**: Parse `head.ref` from the GitHub API response (alongside `head.sha`) and add `HeadBranch` to `PRStatus` - **gitsync**: Wire `HeadBranch` through `refreshOne()` into the DB upsert params - **worker**: Map `HeadBranch` in `chatDiffStatusFromRow()` - **coderd**: Convert `HeadBranch` in `convertChatDiffStatus()` - **codersdk**: Expose as `head_branch` (`*string`, omitempty) in `ChatDiffStatus` API response - **Tests**: Updated `github_test.go` pull JSON fixtures and assertions |
||
|
|
3f7f25b3ee |
fix(chats): enforce desktop connect authorization (#23073)
### Motivation - The desktop watch handler opened a VNC stream using the chat's workspace ID while only relying on workspace read permissions, allowing read-only users to escalate to interactive desktop access. - Enforce connect-level authorization so only actors with `ActionApplicationConnect` or `ActionSSH` can open the desktop stream. ### Description - Added an explicit workspace lookup in `watchChatDesktop` using `GetWorkspaceByID` to obtain a workspace object for authorization. - Require the requester to be authorized for either `policy.ActionApplicationConnect` or `policy.ActionSSH` on the workspace before proceeding to locate agents or connect to the VNC stream, and return `403 Forbidden` when neither permission is present. - The change is minimal and localized to `coderd/chats.go` and does not alter other code paths or behavior when the requester has the necessary connect permissions. ### Testing - Ran `gofmt -w coderd/chats.go` to format the modified file, which succeeded. - Attempted to run the unit test `TestWatchChatDesktop/NoWorkspace` via `go test` in this environment but the test run did not complete within the environment constraints and did not produce a full pass result. - Attempted to run the repository pre-commit/gen steps but they could not complete due to missing developer tooling and services in this environment (e.g. `sqlc`, `mockgen`, `protoc` plugins and test services like Docker/Postgres), so full pre-commit validation did not finish here. - Code review and static validation confirm the added authorization check properly prevents read-only access from opening the desktop VNC stream. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_b_69b46a4ac5c4832ea9d330aeba43c32d) |
||
|
|
ddd1e86a90 |
fix(site): prevent infinite scroll from spamming duplicate chat list requests (#23075)
## Problem The agents sidebar infinite scroll was spamming the `/api/v2/chats` endpoint with duplicate requests at the same offset, caused by the `LoadMoreSentinel` component. ### Root cause `onLoadMore` is an inline arrow function (`() => void chatsQuery.fetchNextPage()`), creating a **new function reference on every render**. The `useEffect` in `LoadMoreSentinel` depended on `[onLoadMore]`, so it tore down and re-created the `IntersectionObserver` on every render. Each new observer immediately fired its callback when the sentinel was already visible, triggering duplicate fetches. ## Fix - Store `onLoadMore` and `isFetchingNextPage` in **refs** so the observer callback always reads the latest values without needing to tear down/re-create. - Create the `IntersectionObserver` **once on mount** (empty deps array). - **Guard** against calling `onLoadMore` while `isFetchingNextPage` is true. ## Tests - **LoadMoreSentinel behavior tests** (6 tests): verifies no duplicate calls across re-renders, proper `isFetchingNextPage` gating, ref-based observer stability, and correct resume after fetch completes. - **`infiniteChats` query factory tests** (6 tests): covers `getNextPageParam` and `queryFn` offset computation to prevent pagination regressions. |
||
|
|
969066b55e |
feat(site): improve cost analytics view (#23069)
Surfaces cache token data in the analytics views and fixes table spacing. ### Changes - **Cache token columns**: Added cache read and cache write token counts to all analytics views (user and admin), from SQL queries through Go SDK types to the frontend tables and summary cards. - **Table spacing fix**: Replaced the bare React fragment in `ChatCostSummaryView` with a `space-y-6` container so the model and chat breakdown tables no longer overlap. ### Data flow `chat_messages` table already stores `cache_read_tokens` and `cache_creation_tokens` (and uses them for cost calculation). This PR aggregates and displays them alongside input/output tokens in: - Summary cards (6 cards: Total Cost, Input, Output, Cache Read, Cache Write, Messages) - Per-model breakdown table - Per-chat breakdown table - Admin per-user table |
||
|
|
f6976fd6c1 |
chore(dogfood): bump mux to 1.4.3 (#23039)
## Summary - bump the dogfood Mux module to 1.4.3 - enable the new restart logic and allow up to 10 restart attempts ## Testing - terraform fmt -check -diff dogfood/coder/main.tf - git diff --check -- dogfood/coder/main.tf - terraform -chdir=dogfood/coder validate |
||
|
|
cbb3841e81 | test(chats): verify cost summaries survive model deletion (#23051) | ||
|
|
36665e17b2 |
feat: add WatchAllWorkspaceBuilds endpoint for autostart scaletests (#22057)
This PR adds a `WatchAllWorkspaces` function with `watch-all-workspaces` endpoint, which can be used to listen on a single global pubsub channel for _all_ workspace build updates, and makes use of it in the autostart scaletest. This negates the need to use a workspace watch pubsub channel _per_ workspace, which has auth overhead associated with each call. This is especially relevant in situations such as the autostart scaletest, where we need to start/stop a set of workspaces before we can configure their autostart config. The overhead associated with all the watch requests skews the scaletest results and makes it harder to reason about the performance of the autostart feature itself. The autostart scaletest also no longer generates its own metrics nor does it wait for all the workspaces to actually start via autostart. We should update the scaletest dashboard after both PRs are merged to measure autostart performance via the new metrics. The new function/endpoint and its usage in the autostart scaletest are gated behind an experiment feature flag, this is something we should discuss whether we want to enable the endpoint in prod by default or not. If so, we can remove the experiment. --------- Signed-off-by: Callum Styan <callumstyan@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Callum Styan <callum@coder.com> |
||
|
|
b492c42624 |
chore(dogfood): add Google Chrome to dogfood image (#23063)
Install Google Chrome stable directly from `dl.google.com`. Ubuntu 22.04 ships `chromium-browser` as a snap-only package, which does not work in Docker containers. ```dockerfile RUN wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \\ apt-get install --yes ./google-chrome-stable_current_amd64.deb && \\ rm google-chrome-stable_current_amd64.deb ``` Verified in a running dogfood workspace: ``` $ google-chrome --version Google Chrome 146.0.7680.75 ``` |
||
|
|
c5b8611c5a |
feat(gitsync): enrich PR status with author, base branch, review info (#23038)
## Summary Adds 7 new fields to the PR status stored by gitsync, all sourced from the existing GitHub API calls (**zero additional HTTP requests**): | Field | Source | Purpose | |---|---|---| | `author_login` | `pull.user.login` | PR author username | | `author_avatar_url` | `pull.user.avatar_url` | PR author avatar for UI | | `base_branch` | `pull.base.ref` | Target branch (e.g. `main`) | | `pr_number` | `pull.number` | Explicit PR number | | `commits` | `pull.commits` | Number of commits in PR | | `approved` | Derived from reviews | True when ≥1 approved, no outstanding changes requested | | `reviewer_count` | Derived from reviews | Distinct reviewers with a decisive state | ## Changes - **`gitprovider/gitprovider.go`**: Added 7 fields to `PRStatus` struct. - **`gitprovider/github.go`**: Expanded the anonymous struct in `FetchPullRequestStatus` to decode new JSON fields. Replaced `hasOutstandingChangesRequested()` with `summarizeReviews()` returning a `reviewStats` struct with `changesRequested`, `approved`, and `reviewerCount`. - **Migration 000434**: Adds 7 columns to `chat_diff_statuses`. - **`queries/chats.sql`**: Updated `UpsertChatDiffStatus` INSERT/VALUES/ON CONFLICT. - **`gitsync/gitsync.go`**: Maps new `PRStatus` fields into upsert params. - **`gitsync/worker.go`**: Maps new columns in row-to-model converter. - **`codersdk/chats.go`**: Added fields to SDK `ChatDiffStatus` type. - **`coderd/chats.go`**: Maps new DB fields in `convertChatDiffStatus()`. - Auto-generated: `models.go`, `queries.sql.go`, `dump.sql`, `typesGenerated.ts`. |
||
|
|
f714f589c5 | fix: fork gvisor to avoid integer overflow (#23055) | ||
|
|
72689c2552 |
fix(coderd): improve error handling in chattest, chattool, and chats (#23047)
- Use t.Errorf in chattest non-streaming helpers so encoding failures fail the test - Thread testing.TB into writeResponsesAPIStreaming and log SSE write errors instead of silently dropping them - Bump createworkspace DB error log from Warn to Error - Use errors.Join for timeout + output error in execute.go |
||
|
|
85509733f3 |
feat: chat desktop frontend (#23006)
https://github.com/user-attachments/assets/26f9c210-01ad-4685-aff1-7629cf3854f1 |
||
|
|
eacabd8390 |
feat(site): add chat cost analytics frontend (#23037)
Add UI components for viewing and managing LLM chat cost analytics. ## Changes - `UserAnalyticsDialog`: personal cost summary with 30-day date range - `ChatCostSummaryView`: shared component for cost breakdowns by model and chat - `ConfigureAgentsDialog`: admin Usage tab with deployment-wide cost rollup - Storybook stories for all new and existing components - Replace `ModelsSection.test.tsx`, `DashboardLayout.test.tsx`, `AuditPage.test.tsx` with Storybook stories - Cost-related API client methods and React Query hooks - Analytics utilities for formatting microdollar values Backend: #23036 |
||
|
|
84527390c6 |
feat: chat desktop backend (#23005)
Implement the backend for the desktop feature for agents. - Adds a new `/api/experimental/chats/$id/desktop` endpoint to coderd which exposes a VNC stream from a [portabledesktop](https://github.com/coder/portabledesktop) process running inside the workspace - Adds a new `spawn_computer_use_agent` tool to chatd, which spawns a subagent that has access to the `computer` tool which lets it interact with the `portabledesktop` process running inside the workspace - Adds the plumbing to make the above possible There's a follow up frontend PR here: https://github.com/coder/coder/pull/23006 |
||
|
|
67f5494665 |
fix(site): allow microphone access for Web Speech API on agents page (#23046)
## Problem The `/agents` page has a voice input feature that uses the Web Speech API (`webkitSpeechRecognition`), but clicking the mic button always results in a `"not-allowed"` error — even when the browser has microphone permission granted. ## Root Cause The `secureHeaders()` function in `site/site.go` sets a `Permissions-Policy` header with `microphone=()`, which completely disables microphone access for the page at the HTTP level. This overrides any browser-level mic permission grants and causes the Web Speech API to immediately fire an `onerror` event with `error: "not-allowed"`. ## Fix Change `microphone=()` to `microphone=(self)`, which: - Allows the Coder origin itself to use the microphone (enabling the Web Speech API voice input) - Still blocks cross-origin iframes from accessing the microphone This is the minimal permission change needed — `(self)` is more restrictive than removing the policy entirely, maintaining the security intent of the original header. ## Testing 1. Navigate to `/agents` 2. Click the mic button in the chat input 3. Verify voice input works (browser will prompt for mic permission if not already granted) 4. Verify `Permissions-Policy` response header now shows `microphone=(self)` instead of `microphone=()` --------- Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> |
||
|
|
9d33c340ec |
fix(coderd): handle ignored errors across coderd packages (#22851)
Handle previously ignored error return values in coderd: - coderd/chats.go: check sendEvent errors, log on failure - coderd/chatd/chattest: thread testing.TB through server structs, replace log.Printf with t.Logf, check writeSSEEvent errors - coderd/chatd/chattool/createworkspace.go: log UpdateChatWorkspace failure instead of discarding both return values - coderd/chatd/chattool/execute.go: surface ProcessOutput error in the timeout message returned to the caller - coderd/provisionerdserver: log stream.Send failure in the DownloadFile error helper |
||
|
|
3bd840fe27 |
build(scripts/lib): allow MAKE_TIMED=1 to show last 20 lines of failed jobs (#22985)
Refs #22978 |
||
|
|
03d0fc4f4c |
fix(coderd): strip markdown code fences from Anthropic task name responses (#23024)
- Adds `extractJSON()` to strip markdown code fences before JSON parsing and wire into the `json.Unmarshal` call in `generateFromAnthropic`. - Accepts variadic `RequestOption` in `generateFromAnthropic` so tests can inject a mock Anthropic server via `WithBaseURL`. - Adds table-driven cases covering bare JSON, fenced with/without language tag, surrounding whitespace, and multiline JSON. - Adds end-to-end cases using `httptest.NewServer` to serve fake Anthropic SSE streams with bare and fenced responses. |
||
|
|
efe114119f |
fix(agent/reaper): run reaper tests in isolated subprocesses (#22894)
Tests that call ForkReap or send signals to their own process now re-exec as isolated subprocesses. This prevents ForkReap's syscall.ForkExec and process-directed signals from interfering with the parent test binary or other tests running in parallel. Also: - Wait for the reaper goroutine to fully exit between subtests to prevent overlapping reapers from competing on Wait4(-1). - Register signal handlers synchronously before spawning the forwarding goroutine so no signal is lost between ForkExec and the handler being ready. |
||
|
|
c3b6284955 |
feat: add chat cost analytics backend (#23036)
Add cost tracking for LLM chat interactions with microdollar precision. ## Changes - Add `chatcost` package for per-message cost calculation using `shopspring/decimal` for intermediate arithmetic - **Ceil rounding policy**: fractional micros round UP to next whole micro (applied once after summing all components) - Database migration: `total_cost_micros` BIGINT column with historical backfill and `created_at` index - API endpoints: per-user cost summary and admin rollup under `/api/experimental/chats/cost/` - SDK types: `ChatCostSummary`, `ChatCostModelBreakdown`, `ChatCostUserRollup` - Fix `modeloptionsgen` to handle `decimal.Decimal` as opaque numeric type - Update frontend pricing test fixtures for string decimal types ## Design decisions - `NULL` = unpriced (no matching model config), `0` = free - Reasoning tokens included in output tokens (no double-counting) - Integer microdollars (BIGINT) for storage and API responses - Price config uses `decimal.Decimal` for exact parsing; totals use `int64` Frontend: #23037 |
||
|
|
1152b61ebb |
fix(site): fix speech recognition race condition and silent errors (#23043)
## Problem
Clicking the microphone button on `/agents` briefly activates recording
then immediately stops, focusing the text input.
## Root causes
**1. Race condition in `start()`** — When aborting a previous
recognition instance, the old instance's `onend` fires
**asynchronously** in real browsers (unlike our mock which fires it
synchronously). The stale `onend` callback then sets `isRecording=false`
and nullifies `recognitionRef.current`, killing the new recording
session. The unit tests didn't catch this because the mock fires `onend`
synchronously inside `abort()`.
**2. Silent `onerror` handler** — The `onerror` callback completely
discarded the error event. If the browser denied mic permission or the
speech service was unreachable (Chrome sends audio to Google servers),
recording silently died with no feedback.
**3. No cleanup on unmount** — The hook leaked a running recognition
instance if the component unmounted while recording.
## Fixes
- Guard `onend`/`onerror` callbacks with `recognitionRef.current !==
recognition` so stale instances are ignored
- Expose `error: string | null` state from the hook; surface it in the
UI ("Mic access denied" / "Voice input failed")
- Add a cleanup `useEffect` that aborts recognition on unmount
- Added 4 new tests covering the race condition, error exposure, and
error clearing
|
||
|
|
5745ff7912 |
test: log DERP debug in CI (#23041)
related to: https://github.com/coder/internal/issues/1387 Sometimes our tests using DERP flake like the above, but we have no information at the DERP layer about why. This enables verbose DERP logging in CI. Logs are kinda spammy, but most tests do not force DERP and so only use it for discovery (disco). A test like TestWorkspaceAgentListeningPorts/OK_BlockDirect drops around 50 DERP packets e.g. ``` t.go:111: 2026-03-13 15:20:52.201 [debu] agent.net.tailnet.net.wgengine: magicsock: got derp-999 packet: "\x04\x00\x00\x00C}\xe0\xb9\x00\x00\x00\x00\x00\x00\x00\x00}\xae;l\xd9Hk8\xa8l\x1cK\xedO{狦)\x18NIw\xc4k\xd2-\x19\xbf\xfb\xdd\x17\xa9b\xac\xfd#\xf7\xcaC\xbe\vq(u=\xa7\x16\xe9\x9aLjS\x1fXL\x19y\xf4\x1dE%\xb3\xff\x9d:8\xa9\x95X\xfe\xf8\x95\x7f\x9dv$\f\xf4\xbe" t.go:111: 2026-03-13 15:20:52.201 [debu] agent.net.tailnet.net.wgengine: magicsock: got derp-999 packet: "\x04\x00\x00\x00C}\xe0\xb9\x01\x00\x00\x00\x00\x00\x00\x00\x05x\xb6RD;\xb4\x80\xb6\x0f\xf6KŠc\xfb1\xbd\x06\xb70K3\x97`\x8d\xd2\x14\xed\xc5\xd6\xc6\xcaV\xbf\x878\xb2Ƥ\xf0\xd5\xf7\xc0\x1b\x9f\x04Y\x03\x17\xd4\x06\xee\xb2G\r){\x9f\xde\xe0(\xb5N\xfejR_\xf6q\xa4\xfaT\x9a\xd8\xcbk\xba\x16K" t.go:111: 2026-03-13 15:20:52.201 [debu] agent.net.tailnet.net.wgengine: magicsock: got derp-999 packet: "\x04\x00\x00\x00C}\xe0\xb9\x02\x00\x00\x00\x00\x00\x00\x00\x1e\x93a\x15\xfev\x81'\xa9?\xe8nR\xce<\x91\x86\xcau@\xb9\xcfɩ\xef\xd1眓\x95\xf3*X^7\x99\x88\xb0|\x8cS\xe4@[\x16\xda\xca\xd4\xd9\x1dP\xd0\xfe\xd9r\x8c\xfcp~dP\xfaK\xe0\xf9y\xb2\x11\x15\xfe\xdcx鷽\xdeF\xf7\x92\xe8" ``` |
||
|
|
4a79af1a0d |
refactor: add chat_message_role enum and content_version column (#23042)
Migration 000434 converts chat_messages.role from text to a Postgres enum, rebuilds the partial index, and adds content_version smallint. The column is backfilled with DEFAULT 0, then the default is dropped so future inserts must set it explicitly. Version 0 uses the role-aware heuristic from #22958. Version 1 (all new inserts) stores []ChatMessagePart JSON for all roles, including system messages. ParseContent takes database.ChatMessage directly and dispatches on version internally. Unknown versions error. All string(codersdk.ChatMessageRole*) casts at DB write sites are replaced with database.ChatMessageRole* constants from sqlc. Refs #22958 |
||
|
|
bdbcd3428b |
feat(coderd/chatd): unify chat storage on SDK parts and fix file-reference rendering (#22958)
File-reference parts in user messages were flattened to `TextContent` at write time because fantasy has no file-reference content type. The frontend never saw them as structured parts. This moves all write paths (user, assistant, tool) from fantasy envelope format to `codersdk.ChatMessagePart`. The streaming layer (`chatloop`) is untouched, the conversion happens at the serialization boundary in `persistStep`. Old rows are still readable. `ParseContent` uses a structural heuristic (`isFantasyEnvelopeFormat`) to distinguish legacy envelopes from SDK parts. We chose this over try/fallback because fantasy envelopes partially unmarshal into `ChatMessagePart` (the `type` field matches) while silently losing content. A guard test enforces that no SDK part can produce the envelope shape. This is forward-only: new rows are unreadable by old code. Chat is behind a feature flag so rollback risk is contained. Also adds a typed `ChatMessageRole` to replace raw strings and `fantasy.MessageRole*` casts at the persistence boundary. The type covers `ChatMessage.Role`, `ChatStreamMessagePart.Role`, the `PublishMessagePart` callback chain, and all DB write sites. `fantasy.MessageRole*` remains only where we build `fantasy.Message` structs for LLM dispatch. Separately, `ProviderMetadata` was leaking to SSE clients via `publishMessagePart`. `StripInternal` now runs on both the SSE and REST paths, covering this. Other cleanup: - Old `db2sdk.contentBlockToPart` silently dropped metadata on text/reasoning/tool-call content. New code preserves it. - `providerMetadataToOptions` now logs warnings instead of silently returning nil. - `db2sdk` shrinks from ~250 lines of parallel conversion to ~15 lines delegating to `chatprompt.ParseContent()`, removing the `fantasy` import entirely. Refs #22821 |
||
|
|
870583224d |
chore: deprecate injected MCP approach in AI Bridge (#23031)
_Disclaimer: implemented by a Coder Agent using Claude Opus 4.6._ Marks the injected MCP approach in AI Bridge as deprecated across the codebase. ## Changes - **`codersdk/deployment.go`**: Deprecated `ExternalAuthConfig.MCPURL`, `.MCPToolAllowRegex`, `.MCPToolDenyRegex` fields; deprecated and hid the `--aibridge-inject-coder-mcp-tools` server flag; deprecated `AIBridgeConfig.InjectCoderMCPTools`. - **`coderd/externalauth/externalauth.go`**: Deprecated `Config.MCPURL`, `.MCPToolAllowRegex`, `.MCPToolDenyRegex`. - **`enterprise/aibridgedserver/aibridgedserver.go`**: Added runtime deprecation warning when `CODER_AIBRIDGE_INJECT_CODER_MCP_TOOLS` is enabled; deprecated `getCoderMCPServerConfig`. - **`enterprise/aibridged/mcp.go`**: Deprecated `MCPProxyBuilder` interface and `MCPProxyFactory` struct. - **`docs/ai-coder/ai-bridge/mcp.md`**: Added deprecation warning banner. |
||
|
|
df2360f56a |
feat(coderd): add consolidated /debug/profile endpoint for pprof collection (#22892)
## Summary Adds a new `GET /api/v2/debug/profile` endpoint that collects multiple pprof profiles in a single request and returns them as a tar.gz archive. This allows collecting profiles (including block and mutex) without requiring `CODER_PPROF_ENABLE` to be set, and without restarting `coderd`. Closes #21679 ## What it does The endpoint: - Temporarily enables block and mutex profiling (normally disabled at runtime) - Runs CPU profile and/or trace for a configurable duration (default 10s, max 60s) - Collects snapshot profiles (heap, allocs, block, mutex, goroutine, threadcreate) - Returns a tar.gz archive containing all requested `.prof` files - Uses an atomic bool to prevent concurrent collections (returns 409 Conflict) - Is protected by the existing debug endpoint RBAC (owner-only) **Supported profile types:** cpu, heap, allocs, block, mutex, goroutine, threadcreate, trace **Query parameters:** - `duration`: How long to run timed profiles (default: `10s`, max: `60s`) - `profiles`: Comma-separated list of profile types (default: `cpu,heap,allocs,block,mutex,goroutine`) ## Additional changes - **SDK client method** (`codersdk.Client.DebugCollectProfile`) for easy programmatic access - **`coder support bundle --pprof` integration**: tries the consolidated endpoint first, falls back to individual `/debug/pprof/*` endpoints for older servers - **8 new tests** covering defaults, custom profiles, trace+CPU, validation errors, authorization, and conflict detection |
||
|
|
cc6716c730 | fix(scripts): allow graceful shutdown when --debug/dlv is used in develop.sh (#23023) | ||
|
|
836a2112b6 |
feat(dogfood): clean up named Docker volumes and Go build cache cron (#23026)
Docker keeps named volumes around, even if they're dangling. During development users generate a lot of named coder- volumes and the like. These are now cleaned on shutdown once they are 30 days old. For long running workspaces, go build cache also accumulates, so now we clean these up via cron as well. All cache older than 2 days is wiped and the cron schedule is based on workspace ID to distribute the load. |
||
|
|
690e3a87d8 |
feat: move chat messages to dedicated /chats/{id}/messages endpoint (#23021)
## Summary
Moves the messages response out of `GET /chats/{id}` and into a
dedicated `GET /chats/{id}/messages` endpoint.
### Backend
- `GET /chats/{id}` now returns just the `Chat` object (no messages)
- `GET /chats/{id}/messages` is a new endpoint returning
`ChatMessagesResponse` with `messages` and `queued_messages`
- Added `ChatMessagesResponse` SDK type and `GetChatMessages` client
method
### Frontend
- `getChat()` API method returns `Chat` instead of `ChatWithMessages`
- Added `getChatMessages()` API method for the new endpoint
- Split `chatQuery` into two: `chatQuery` (metadata) and
`chatMessagesQuery` (messages)
- Updated all cache mutations, optimistic updates, and websocket
handlers
- Updated tests and stories
### Files changed
| File | Change |
|---|---|
| `coderd/coderd.go` | Register `GET /messages` route |
| `coderd/chats.go` | Simplify `getChat`, add `getChatMessages` handler
|
| `codersdk/chats.go` | New type + method, update `GetChat` return |
| `site/src/api/api.ts` | New method, update `getChat` |
| `site/src/api/queries/chats.ts` | New query, update cache mutations |
| `site/src/pages/AgentsPage/AgentDetail.tsx` | Use separate queries |
| `site/src/pages/AgentsPage/AgentDetail/ChatContext.ts` | Update types
and cache writes |
| `site/src/pages/AgentsPage/AgentsPage.tsx` | Update websocket cache
handler |
|
||
|
|
0e7e0a959e |
feat(site): add voice-to-text input to agent chat (#23022)
## Summary Adds a microphone button to the agent chat input for browser-native voice-to-text transcription using the Web Speech API. ## Changes ### New: `site/src/hooks/useSpeechRecognition.ts` - Custom React hook wrapping the Web Speech API (`SpeechRecognition` / `webkitSpeechRecognition`) - Feature-detects browser support via `isSupported` - Provides `start()`, `stop()`, and `cancel()` controls - Accumulates real-time transcript from interim and final recognition results - Inline TypeScript declarations for the Web Speech API types ### Modified: `site/src/pages/AgentsPage/AgentChatInput.tsx` - **Mic button**: Appears to the right of the image attach button when the browser supports the Speech Recognition API. Shows a microphone icon when idle, X icon when recording. - **Send button**: Transforms into a checkmark during recording to accept the transcription. Always enabled during recording. - **Editor sync**: Live-updates the Lexical editor with the transcription as the user speaks. Preserves any pre-existing text. - **Cancel**: Restores the editor to its pre-recording content. ## How it works 1. User clicks the mic button → recording starts, real-time transcript appears in the editor 2. User clicks the checkmark (send button) → recording stops, transcribed text stays 3. User clicks X (mic button) → recording stops, editor reverts to original content |
||
|
|
ff156772f2 |
fix(coderd/database): move context creation to first use in migration tests (#23032)
The timeout was started before the unbounded Stepper loop, so under CI load the deadline could expire before reaching the operations that actually use it. Also bumps TestMigration000387 from WaitLong to WaitSuperLong. Fixes coder/internal#1398 |
||
|
|
a5400b2208 | docs: add updated grafana dashboard with Client information (#23027) | ||
|
|
4e2640e506 |
fix(site): WCAG 2.1 AA remediation — landmarks, semantics, and a11y tooling (#22746)
## Summary Targeted WCAG 2.1 AA accessibility remediation — continuation of #22673 — addressing remaining semantic, landmark, and tooling gaps identified in the frontend accessibility review. ### Changes #### Document semantics (WCAG 3.1.1) - **`site/index.html`**: Added `<html lang="en">` root wrapper so screen readers and browser features correctly identify the document language. #### Landmark & bypass (WCAG 1.3.1, 2.4.1) - **`DashboardLayout.tsx`**: Replaced `<div id="main-content">` with `<main id="main-content">` so assistive technology exposes a proper main landmark and the skip link targets a semantic region. #### Table header relationships (WCAG 1.3.1) - **`Table.tsx`**: `TableHead` now renders `scope="col"` by default (overridable via prop), giving data cells an explicit header relationship. #### Semantic interactive controls (WCAG 2.1.1, 4.1.2) - **`AuditLogRow.tsx`**: Replaced `<div role="button" tabIndex={0}>` with native `<button type="button">`, removing the manual keyboard handler (native button provides Enter/Space for free). - **`Autocomplete.tsx`**: Replaced clear `<span role="button" tabIndex={0}>` with native `<button type="button" aria-label="Clear selection">`. #### Reduced motion (WCAG 2.3.3 best practice) - **`index.css`**: Added global `@media (prefers-reduced-motion: reduce)` block that suppresses non-essential animations and transitions. #### Accessibility regression tooling - **Storybook**: Added `@storybook/addon-a11y` (version-matched to existing Storybook 10.x). - **vitest-axe**: Added `vitest-axe` with setup wiring and an exemplar `Table.axe.test.tsx` that runs axe-core assertions in vitest. ### Test plan - 12 new/updated tests pass across 5 test files: - `DashboardLayout.test.tsx` — main landmark + skip link behavior - `Table.test.tsx` — scope default + override - `Table.axe.test.tsx` — axe-core violation scan - `AuditPage.test.tsx` — keyboard toggle with native button - `Autocomplete.test.tsx` — clear control semantics - `pnpm lint` clean (biome, TypeScript, circular deps) - Manual keyboard traversal: skip link → main content, audit row toggle, autocomplete clear |
||
|
|
6104a000d1 |
refactor(healthcheck): reduce test boilerplate with healthyChecker helper (#23028)
## Summary Extract a `healthyChecker()` test helper that returns an all-healthy baseline `testChecker` in `coderd/healthcheck`. Each `TestHealthcheck` table-driven test case now only overrides the single report field being tested, instead of repeating all 6 healthy report structs. - Reduces `healthcheck_test.go` from 603 to 341 lines (~260 lines, 43% reduction) - Test coverage unchanged at 77.2% - All test cases and assertions preserved exactly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |