Commit Graph
100 Commits
Author SHA1 Message Date
Cian Johnston 32acc73047 ci: bump runner sizes (#23514)
Bumps the runners changed in 5544a60b6e to larger sizes.
2026-03-24 18:38:03 +00:00
Cian Johnston 5544a60b6e ci: yeet depot runners in favour of GitHub runners (#23508)
Depot runners are running out of disk space and blocking builds.
Temporarily switch the build and release jobs from depot runners to
GitHub-hosted runners:

- `ci.yaml` build job: `depot-ubuntu-22.04-8` → `ubuntu-latest`
- `release.yaml` check-perms + release jobs: `depot-ubuntu-22.04-8` →
`ubuntu-latest`

**This is intended to be reverted once depot resolves their disk space
issues.**

> 🤖 This PR was created with the help of Coder Agents, and will be
reviewed by my human. 🧑‍💻
2026-03-24 17:19:38 +00:00
Cian Johnston fd1e2f0dd9 fix(coderd/database/dbauthz): skip Accounting check when sub-test filtering (#23281)
- Detect `-testify.m` sub-test filtering in `SetupSuite` and skip the `Accounting` check.

> 🤖 This PR was created with the help of Coder Agents, and was reviewed by my human. 🧑‍💻
2026-03-24 14:58:04 +00:00
Cian Johnston cbd56d33d4 ci: disable go cache for build jobs to prevent disk space exhaustion (#23484)
Disables Go cache for the setup-go step to workaround depot runner disk space issues.
2026-03-24 11:17:39 +00:00
Cian Johnston 9e4c283370 test: share coderdtest instances in OAuth2 validation tests (#23455)
Consolidates invocations of `coderdtest.New` to a single shared instance per
parent for the following tests:

- `TestOAuth2ClientMetadataValidation`
- `TestOAuth2ClientNameValidation`
- `TestOAuth2ClientScopeValidation`
- `TestOAuth2ClientMetadataEdgeCases`

> 🤖 This PR was created with the help of Coder Agents, and was
reviewed by my human. 🧑‍💻
2026-03-23 21:03:34 +00:00
Cian Johnston 956f6b2473 test: share coderdtest instances to stop paying the startup tax 22 times (#23454)
Consolidates 6 tests that spun up separate coderdtest instances per sub-test into a single shared instance per parent. 

> 🤖 This PR was created with the help of Coder Agents, and has been
reviewed by my human. 🧑‍💻
2026-03-23 19:54:43 +00:00
Cian Johnston 3b268c95d3 chore(dogfood): evict 22 freeloading tools from the Dockerfile (#23378)
Removes unused tools from dogfood Dockerfile:
- Go tools `moq`, `go-swagger`, `goreleaser`, `goveralls`, `kind`,
`helm-docs`, `gcr-cleaner-cli`
- curl-installed `cloud_sql_proxy`, `dive`, `docker-credential-gcr`, `grype`,
`kube-linter`, `stripe` CLI, `terragrunt`, `yq` v3, GoLand 2021.2 , ANTLR v4 jar
- apt packages `cmake`, `google-cloud-sdk-datastore-emulator`, `graphviz`, `packer`

> 🤖 This PR was created with the help of Coder Agents, and was reviewed by my human. 🧑‍💻
2026-03-23 18:25:58 +00:00
Cian Johnston 80a172f932 chore: move chatd and related packages to /x/ subpackage (#23445)
- Moves `coderd/chatd/`, `coderd/gitsync/`, `enterprise/coderd/chatd/`
under `x/` parent directories to signal instability
- Adds `Experimental:` glue code comments in `coderd/coderd.go`

> 🤖 This PR was created with the help of Coder Agents, and was
reviewed by my human. 🧑‍💻
2026-03-23 17:34:43 +00:00
Cian Johnston ef14654078 chore: move chat methods to ExperimentalClient (#23441)
- Changes all 41 chat method receivers in `codersdk/chats.go` from
`*Client` to `*ExperimentalClient` to ensure that callers are aware that
these reference potentially unstable `/api/experimental` endpoints.


> 🤖 This PR was created with the help of Coder Agents, and has been
reviewed by my human. 🧑‍💻
2026-03-23 14:32:11 +00:00
Cian Johnston ab86ed0df8 fix(site): stop hijacking navigation after archive-and-delete settles (#23372)
- Guard both `onSettled` callbacks in
`archiveAndDeleteMutation.mutate()` with `shouldNavigateAfterArchive()`,
which checks whether the user is still viewing the archived chat (or a
sub-agent of it) before calling `navigate("/agents")`
- Extract `shouldNavigateAfterArchive` into `agentWorkspaceUtils.ts`
with 6 unit test cases covering: direct match, different chat, no active
chat, sub-agent of archived parent, sub-agent of different parent, and
cache-cleared fallback
- Look up the active chat's `root_chat_id` from the per-chat query cache
(stable across WebSocket eviction of sub-agents) to handle the sub-agent
case

> 🤖 This PR was created with the help of Coder Agents, and has been
reviewed by my human. 🧑‍💻
2026-03-23 11:28:06 +00:00
Cian Johnston ff8dcca2c7 feat: add global chat workspace TTL setting (#23265)
- Add `agents_workspace_ttl` site config (default: whatever the template
says a.k.a. `0s`)
- Expose via GET/PUT `/api/experimental/chats/config/workspace-ttl`
- Chat tool reads setting and passes `TTLMillis` on workspace creation
- Existing autostop infrastructure handles the rest (zero changes to
LifecycleExecutor, CalculateAutostop, or activity bumping)
- ⚠️ Template-level `UserAutostopEnabled=false` overrides this global
default. Not touching this.
- Frontend: "Workspace Lifetime" control in /agents/settings Behavior
tab (admin-only)

> This PR was created with the help of Coder Agents, and has been
reviewed by several humans and robots. 🤖🤝🧑‍💻
2026-03-20 17:38:39 +00:00
Cian Johnston f1d333f0e6 refactor: deduplicate utility helpers across the codebase (#23338)
Audited exported helpers in `coderd/util/*`, `testutil`, `cryptorand`,
and friends, then replaced duplicated implementations with canonical
versions.

- **fix: `maps.SortedKeys` generic signature** — value type was
hardcoded to `any`, making it impossible to actually call. Added second
type parameter `V any`. Added table-driven tests with `cmp.Diff`.
- **refactor: replace ad-hoc ptr helpers with `ptr.Ref`** — removed
`int64Ptr`, `stringPtr`, `boolPtr`, `i64ptr`, `strPtr`, `PtrInt32`
across 6 files.
- **refactor: replace local `sortedKeys`/`sortKeys` with
`maps.SortedKeys`** — now that the signature is fixed, scripts can use
it.
- **refactor: replace hand-rolled `capitalize` with
`strings.Capitalize`** — the typegen version was also not UTF-8 safe.

> 🤖 This PR was created with the help of Coder Agents, and was reviewed
by my human. 🧑‍💻
2026-03-20 15:12:41 +00:00
Cian Johnston 4c9041b270 chore: evict trivy from the dogfood Dockerfile (#23367)
- Remove `TRIVY_VERSION` ARG and trivy CLI install block from
`dogfood/coder/Dockerfile`
- The `trivy` job in `.github/workflows/security.yaml` is kept — it uses
`aquasecurity/trivy-action` pinned to a known-good commit

> 🤖 This PR was created with the help of Coder Agents, and was reviewed
by my human. 🧑‍💻
2026-03-20 14:52:11 +00:00
Cian JohnstonandCopilot c8e58575e0 chore: attempt to nudge agents away from dbauthz.AsSystemRestricted (#23326)
Adds a warning comment to dbauthz.AsSystemRestricted to hopefully nudge agents away from it.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-20 14:18:18 +02:00
Cian Johnston d8cad81ada fix(coderd/chatd): rate-limit stream drop WARN logs to avoid log spam (#23340)
- Rate-limit "chat stream buffer full" and "dropping chat stream event"
  WARN logs to at most once per 10s per chat.
- Intermediate drops not logged; WARN includes `dropped_count`.
- Per-chat tracking on `chatStreamState` using timestamp comparison
  against `quartz.Clock` — no global tickers, no new `Server` fields.
- Subscriber and buffer drop counters reset at all lifecycle boundaries.

> 🤖 This PR was created with the help of Coder Agents, and was reviewed
by my human. 🧑‍💻
2026-03-20 12:16:39 +00:00
Cian Johnston 06c50d13ad fix(cli): exorcise the DERP healthcheck demon from TestSupportBundle (#23337)
- Replace real healthcheck with mock `HealthcheckFunc` that returns a
canned report instantly
- Remove healthcheck cache-seeding goroutine/channel workaround
- Remove `HealthcheckTimeout: testutil.WaitSuperLong` (no longer needed)
- Reduce `setupCtx` from `WaitSuperLong` (60s) to `WaitLong` (25s)

The DERP healthcheck performs real network operations (portmapper
gateway probing, STUN) that hang for 60s+ on macOS CI runners. Since
`TestSupportBundle` validates bundle generation, not healthcheck
correctness, a canned report eliminates this entire class of flake.

Fixes coder/internal#272

> 🤖 This PR was created with the help of Coder Agents, and was reviewed
by my human. 🧑‍💻
2026-03-20 09:46:13 +00:00
Cian Johnston 2f50e89afd fix(coderd): bump workspace autostop deadline on chat heartbeat (#23314)
- Wire `workspacestats.ActivityBumpWorkspace` into `trackWorkspaceUsage`
so the workspace build deadline is extended each time the chat heartbeat
fires
- Prevents mid-conversation autostop for chat workspaces
- Updates `TestHeartbeatBumpsWorkspaceUsage` verifying the deadline bump

> This PR was created with the help of Coder Agents, and was reviewed by two humans and their pet robots 🧑‍💻🤝🤖
2026-03-19 22:07:20 +00:00
Cian Johnston 7c3c7bb5e6 refactor: extract test helpers in coderd/jobreaper to reduce duplication (#23001) 2026-03-19 21:51:26 +00:00
Cian Johnston a908d51097 fix(site): prevent scroll overshoot in diff viewer end spacer (#23305)
- Replace fixed `100vh` spacer at bottom of diff list with a dynamically
sized one
- Adds "X files changed" message to the bottom of the diff

> This PR was created with the help of Coder Agents, and was reviewed by several humans and robots. 🧑‍💻🤝🤖
2026-03-19 18:39:39 +00:00
Cian Johnston c107d2bf5d feat: add confirmation dialog to archive & delete workspace action (#23150)
* Adds a "molly-guard" to require users to type the workspace name
before the 'Archive & delete workspace' action fires. This prevents
accidental deletion of 'pet' workspaces.
* This is only shown for workspaces created *before* the chat was
created. The logic here is that any workspace that existed previous to
the chat *cannot* have been created by the chat.
2026-03-19 15:22:55 +00:00
Cian Johnston be1c06dec9 feat: add endpoint and CLI for users to view their own OIDC claims (#23053)
- Adds a new API endpoint `GET /api/v2/users/oidc-claims` that returns
only the **merged claims** (not the separate id_token/userinfo
breakdown). Scoped exclusively to the authenticated user's own identity
— no user parameter, so users cannot view each other's claims.
- Adds a new CLI command:** `coder users oidc-claims` that hits the
above endpoint.
- The existing owner-only debug endpoint is preserved unchanged for
admins who need the full claim breakdown.


> 🤖 This PR was created with the help of Coder Agents, and will be
reviewed by my human. 🧑‍💻
2026-03-18 22:10:04 +00:00
Cian Johnston 14ed3e3644 feat: bump workspace last_used_at on chat heartbeat (#23205)
- coderd: Wires `options.WorkspaceUsageTracker` into the chatd config.
- chatd: Adds `UsageTracker` and calls `UsageTracker.Add(workspaceID)`
on each heartbeat tick
- chatd: adds tests to verify `last_used_at` bump behaviour

> 🤖 This PR was created with the help of Coder Agents, and will be
reviewed by my human. 🧑‍💻
2026-03-18 19:07:21 +00:00
Cian Johnston 0b13ba978a fix: rename chat logger from coderd.chats.chat-processor to coderd.chatd.processor (#23246)
- Rename logger `coderd.chats` to `coderd.chatd` in `coderd.go`
- Rename sub-logger `chat-processor` to `processor` in `chatd/chatd.go`
2026-03-18 17:48:47 +00:00
Cian JohnstonandCopilot Autofix powered by AI 65b7658568 chore: extract testutil.FakeSink for slog test assertions (#23208)
Follow-up to [review comment on
#23025](https://github.com/coder/coder/pull/23025#discussion_r2930309487)
from @mafredri.

Extracts the repeated `logSink` / `fakeSink` test pattern into a shared
`testutil.FakeSink` and migrates all existing call sites.

> 🤖 This PR was created with the help of Coder Agents, and will be
reviewed by my human. 🧑‍💻

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-18 17:02:38 +00:00
Cian Johnston fe82d0aeb9 fix: allow member users to generate support bundles (#23040)
Fixes AIGOV-141

The `coder support bundle` command previously required admin permissions
(`Read DeploymentConfig`) and would abort entirely for non-admin
`member` users with:

```
failed authorization check: cannot Read DeploymentValues
```

This change makes the command **degrade gracefully** instead of failing
outright.

<details>
<summary>
Changes
</summary>

### `support/support.go`
- **`Run()`**: The authorization check for `Read DeploymentValues` is
now a soft warning instead of a hard gate. Unauthenticated users (401)
still fail, but authenticated users with insufficient permissions
proceed with reduced data.
- **`DeploymentInfo()`**: `DeploymentConfig` and `DebugHealth` fetches
now handle 403/401 responses gracefully, matching the existing pattern
used by `DeploymentStats`, `Entitlements`, and `HealthSettings`.
- **`NetworkInfo()`**: Coordinator debug and tailnet debug fetches now
check response status codes for 403/401 before reading the body.

### `cli/support.go`
- **`summarizeBundle()`**: No longer returns early when `Config` or
`HealthReport` is nil. Instead prints warnings and continues summarizing
available data (e.g., netcheck).

### Tests
- `MissingPrivilege` → `MemberNoWorkspace`: Asserts member users can
generate a bundle successfully with degraded admin-only data.
- `NoPrivilege` → `MemberCanGenerateBundle`: Asserts the CLI produces a
valid zip bundle for member users.
- All existing tests continue to pass (`NoAuth`, `OK`, `OK_NoWorkspace`,
`DontPanic`, etc.).

## Behavior matrix

| User type | Before | After |
|---|---|---|
| **Admin** | Full bundle | Full bundle (no change) |
| **Member** | Hard error | Bundle with degraded admin-only data |
| **Unauthenticated** | Hard error | Hard error (no change) |

Related to PRODUCT-182
2026-03-18 13:43:10 +00:00
Cian Johnston f8dff3f758 fix: improve push notification message shown on subscribe (#23052)
Updates push notification message for test notification.
2026-03-16 14:52:31 +00:00
Cian Johnston 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).
2026-03-16 09:14:24 +00:00
Cian Johnston 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.
2026-03-13 17:35:26 +00:00
Cian JohnstonandClaude Opus 4.6 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>
2026-03-13 10:40:57 +00:00
Cian Johnston 8714aa4637 fix(coderd): downgrade heartbeat ping errors for closed connections to debug (#23025)
- `coderd/httpapi/websocket.go`: add `net.ErrClosed` +
`websocket.CloseStatus` checks; extract `heartbeatCloseWith` with
`quartz.Clock` parameter for testability
- `coderd/httpapi/websocket_internal_test.go`: new test file
2026-03-13 10:38:39 +00:00
Cian Johnston e9025f91e8 chore(db): remove 23 unused database methods (#22999)
Removes 22 database query methods with no callers outside generated code
and the dbauthz wrapper layer (~1,600 lines).

**Security keys (6)** — superseded by `cryptokeys` package:
`GetAppSecurityKey`, `UpsertAppSecurityKey`, `GetOAuthSigningKey`,
`UpsertOAuthSigningKey`, `GetCoordinatorResumeTokenSigningKey`,
`UpsertCoordinatorResumeTokenSigningKey`

**Superseded queries (4):**
- `GetProvisionerJobsByIDs` → `GetProvisionerJobsByIDsWithQueuePosition`
- `GetDeploymentDAUs` / `GetTemplateDAUs` →
`GetTemplateInsightsByInterval`
- `GetWorkspaceBuildParametersByBuildIDs` + its `GetAuthorized...`
variant → unused

**OAuth2 (2):**
`GetOAuth2ProviderAppByRegistrationToken`,
`UpdateOAuth2ProviderAppSecretByID`

**Chat (4)** — pre-wired with no callers:
`GetChatModelConfigByProviderAndModel`, `DeleteChatMessagesByChatID`,
`ListChatsByRootID`, `ListChildChatsByParentID`

**Other (6):**
`DeleteGitSSHKey`, `UpdateUserLinkedID`, `GetFileIDByTemplateVersionID`,
`GetTemplateVersionHasAITask`, `InsertUserGroupsByName`,
`RemoveUserFromAllGroups`
2026-03-12 21:32:57 +00:00
Cian Johnston 2d7dd73106 chore(httpapi): do not log context.Canceled as error (#22933)
A cursory glance at Grafana for error-level logs showed that the
following log line was appearing regularly:

```
2026-03-11 05:17:59.169 [erro]  coderd: failed to heartbeat ping  trace=xxx  span=xxx  request_id=xxx ...
    error= failed to ping:
               github.com/coder/coder/v2/coderd/httpapi.pingWithTimeout
                   /home/runner/work/coder/coder/coderd/httpapi/websocket.go:46
             - failed to ping: failed to wait for pong: context canceled
```

This seems to be an "expected" error when the parent context is canceled
so doesn't make sense to log at level ERROR.


NOTE: I also saw this a bit and wonder if it also deserves similar
treatment:

```
2026-03-11 05:10:53.229 [erro]  coderd.inbox_notifications_watcher: failed to heartbeat ping  trace=xxx  span=xxx  request_id=xxx ...
    error= failed to ping:
               github.com/coder/coder/v2/coderd/httpapi.pingWithTimeout
                   /home/runner/work/coder/coder/coderd/httpapi/websocket.go:46
             - failed to ping: failed to write control frame opPing: use of closed network connection
```
2026-03-11 09:48:07 +00:00
Cian Johnston bc27274aba feat(coderd): refactors github pr sync functionality (#22715)
- Adds `_API_BASE_URL` to `CODER_EXTERNAL_AUTH_CONFIG_`
- Extracts and refactors existing GitHub PR sync logic to new packages
`coderd/gitsync` and `coderd/externalauth/gitprovider`
- Associated wiring and tests

Created using Opus 4.6
2026-03-10 18:46:01 +00:00
Cian Johnston 4c63ed7602 fix(workspaceapps): use fresh context in LastUsedAt assertions (#22863)
## Summary

The `assertWorkspaceLastUsedAtUpdated` and
`assertWorkspaceLastUsedAtNotUpdated` test helpers previously accepted a
`context.Context`, which callers shared with preceding HTTP requests. In
`ProxyError` tests the request targets a fake unreachable app
(`http://127.1.0.1:396`), and the reverse-proxy connection timeout can
consume most of the context budget — especially on Windows — leaving too
little time for the `testutil.Eventually` polling loop and causing
flakes.

## Changes

Replace the `context.Context` parameter with a `time.Duration` so each
assertion creates its own fresh context internally. This:

- Makes the timeout budget explicit at every call site
- Structurally prevents shared-context starvation
- Fixes the class of flake, not just the two known-failing subtests

All 34 active call sites updated to pass `testutil.WaitLong`.

Fixes coder/internal#1385
2026-03-10 16:53:28 +00:00
Cian Johnston 12bdbc693f docs: remove experimental chat API from generated docs (#22897)
The chat API is experimental (behind `ExperimentAgents`) and not ready
for public documentation yet. This removes swagger annotations from the
chat handlers so they no longer appear in the generated API reference at
https://coder.com/docs/reference/api/chats.

## Changes
- Remove `@swagger` annotations from 5 chat handlers in
`coderd/chats.go`
- Regenerate `coderd/apidoc/swagger.json` and `docs.go`
- Delete `docs/reference/api/chats.md`
- Remove Chats entry from `docs/manifest.json`
2026-03-10 15:04:08 +00:00
Cian Johnston c933ddcffd fix(agents): persist system prompt server-side instead of localStorage (#22857)
## Problem

The Admin → Agents → System Prompt textarea saved only to the browser's
`localStorage`. The value was never sent to the backend, never stored in
the database, and never injected into chats. Entering text, clicking
Save, and refreshing the page showed no changes — the prompt was
effectively a no-op.

## Root Cause

Three disconnected layers:
1. **Frontend** wrote to `localStorage`, never called an API.
2. **`handleCreateChat`** never read `savedSystemPrompt`.
3. **Backend** hardcoded `chatd.DefaultSystemPrompt` on every chat
creation — no field in `CreateChatRequest` accepted a custom prompt.

## Changes

### Database
- Added `GetChatSystemPrompt` / `UpsertChatSystemPrompt` queries on the
existing `site_configs` table (no migration needed).

### API
- `GET /api/experimental/chats/system-prompt` — returns the configured
prompt (any authenticated user).
- `PUT /api/experimental/chats/system-prompt` — sets the prompt
(admin-only, `rbac: deployment_config update`).
- Input validation: max 32 KiB prompt length.

### Backend
- `resolvedChatSystemPrompt(ctx)` checks for a custom prompt in the DB,
falls back to `chatd.DefaultSystemPrompt` when empty/unset.
- Logs a warning on DB errors instead of silently swallowing them.
- Replaced the hardcoded `defaultChatSystemPrompt()` call in chat
creation.

### Frontend
- Replaced `localStorage` read/write with React Query
`useQuery`/`useMutation` backed by the new endpoints.
- Fixed `useEffect` draft sync to avoid clobbering in-progress user
edits on refetch.
- Added `try/catch` error handling on save (draft stays dirty for
retry).
- Save button disabled during mutation (`isSavingSystemPrompt`).
- Query key follows kebab-case convention (`chat-system-prompt`).

### UX
- Added hint: "When empty, the built-in default prompt is used."

### Tests
- `TestChatSystemPrompt`: GET returns empty when unset, admin can set,
non-admin gets 403.
- dbauthz `TestMethodTestSuite` coverage for both new querier methods.
2026-03-10 11:46:53 +00:00
Cian Johnston f07e266904 fix(coderd): use dbtime.Now() for tailnet telemetry timestamps (#22861)
Fixes a flaky test (`TestUserTailnetTelemetry/invalid_header`) caused by
sub-microsecond precision mismatch between `time.Now()` calls on
Windows.

The server used `time.Now()` (nanosecond precision) for `ConnectedAt`
and `DisconnectedAt`, while the test compared against its own
`time.Now()`. On Windows, wall-clock jitter can cause the server
timestamp to appear slightly before the test's `predialTime`.

Switch to `dbtime.Now()` which rounds to microsecond precision (matching
Postgres), consistent with all other timestamps in `workspaceagents.go`.

Relates to: https://github.com/coder/internal/issues/1390
2026-03-09 20:37:05 +00:00
Cian Johnston 5b7ba93cb2 fix(site): only use git watcher when workspace agent connected (#22714)
Adds a guard + some unit tests to ensure that we don't try to fetch git
changes if there's no workspace agent from which to do so.

Generated by Claude Opus 4.6 but read using Cian's eyeballs.
2026-03-09 08:53:00 +00:00
Cian Johnston 81468323e0 fix(coderd): use dbtime.Now() instead of time.Now() in test assertions against DB timestamps (#22685)
`time.Now()` has nanosecond precision while Postgres timestamps are
microsecond precision. When tests compare `time.Now()` against
DB-sourced timestamps using `Before`/`After`/`WithinRange`/etc., there
is a non-zero flake risk from the precision mismatch.

This replaces `time.Now()` with `dbtime.Now()` (which rounds to
microsecond precision) in all test assertions that compare against
database timestamps.

Follows from #22684.

## Changes (11 files)

| File | Changes |
|---|---|
| `coderd/apikey_test.go` | 11 comparisons with `ExpiresAt` |
| `coderd/users_test.go` | 2 comparisons with `ExpiresAt` |
| `coderd/oauth2_test.go` | 1 comparison with `token.Expiry` |
| `coderd/workspaces_test.go` | 2 comparisons with `DormantAt` |
| `coderd/workspaceagents_test.go` | 3 comparisons with
`ConnectedAt`/`DisconnectedAt` |
| `coderd/workspaceapps/db_test.go` | 1 comparison with `token.Expiry` |
| `coderd/provisionerdserver/provisionerdserver_test.go` | 1 comparison
with `key.ExpiresAt` |
| `enterprise/coderd/workspaces_test.go` | 1 comparison with `DormantAt`
|
| `enterprise/coderd/license/license_test.go` | 3 `NotBefore` values |
| `enterprise/coderd/licenses_test.go` | 2 `NotBefore` values |
| `enterprise/coderd/users_test.go` | 3 `Next()` comparisons |

## Not changed (intentionally)

- `scaletest/placebo/run_test.go` — compares wall-clock elapsed time,
not DB timestamps
- `cli/server_test.go`, `coderd/jwtutils/jwt_test.go`,
`enterprise/aibridgeproxyd/aibridgeproxyd_test.go` — TLS cert fields,
not DB-stored
- `coderd/azureidentity/azureidentity_test.go` — Azure cert expiry, not
DB


🤖 Generated by Claude Opus 4.6 but reviewed manually.
2026-03-06 09:14:11 +00:00
Cian Johnston 0b1e4880bd chore(cli): fix TestTokens harder (#22684)
`time.Now()` is greater than microsecond precision while timestamps we
store in Postgres are only microsecond precision. Flake potential is
non-zero.
2026-03-06 00:04:09 +00:00
Cian Johnston 89cee2dd81 chore(cli): fix flaky temporal assertion in TestTokens (#22654)
Fixes https://github.com/coder/internal/issues/1379
2026-03-05 10:18:51 +00:00
Cian JohnstonandAtif Ali 9c91f472b9 ci: remove temporary deploy override (#22389)
Merge after Tuesday March 3rd.

Co-authored-by: Atif Ali <atif@coder.com>
2026-03-05 09:47:15 +00:00
Cian Johnston d0a51e1752 fix: use testutil.Eventually in chatd interrupt test (#22653)
Follow-up to #22630. Addresses [review
feedback](https://github.com/coder/coder/pull/22630#pullrequestreview-2953419963)
that was missed due to auto-merge.

## Changes

Replaces three `require.Eventually` calls with `testutil.Eventually` in
`TestInterruptChatDoesNotSendWebPushNotification`, linking the condition
to the existing test context (`ctx`) created on line 1194. This ensures
the test respects context cancellation instead of using a standalone
timeout/tick pattern.
2026-03-05 09:42:34 +00:00
Cian Johnston 4d0d187806 fix(chatd): wait for startup scripts before returning from create_workspace (#22498)
The `create_workspace` tool waited for the workspace build to succeed
and the agent to become connectable, but did not wait for the agent's
startup scripts (e.g. git clone) to finish. This caused agents to
attempt file operations on repositories that hadn't been cloned yet.

Add a waitForStartupScripts step that polls the agent's lifecycle_state
via GetWorkspaceAgentLifecycleStateByID until it transitions out of
created/starting into a terminal state (ready, start_error, or
start_timeout). The tool now only returns success once the workspace is
fully initialized.

If the scripts fail or time out, the tool still returns (non-fatal) with
an appropriate agent_status so the model knows something went wrong.

Created using thingies (Opus 4.6 Max)
2026-03-05 09:42:12 +00:00
Cian Johnston 8a095ae722 fix(site): remove ugly webpush button (#22560) 2026-03-03 16:44:46 +00:00
Cian Johnston 88465ea48a chore: misc improvements to compose.dev.yaml (#22541)
- Unexposes port 5432 so it doesn't conflict with existing databases.
You can still hop into the DB if you need.
- Updates multiple CODER_ envs to sensible defaults, overrideable via env
2026-03-03 12:07:57 +00:00
Cian Johnston 3c4a416b55 feat(site): add Open Terminal and Copy SSH Command to agent chat TopBar (#22529)
Adds two new items to the agent chat TopBar dropdown menu:

- **Open Terminal**: opens the workspace web terminal in a new browser
window, reusing the existing `getTerminalHref`/`openAppInNewWindow`
infra.
- **Copy SSH Command**: copies the SSH command (e.g. `ssh
agent.workspace.owner.suffix`) to the clipboard with a toast
confirmation. Only shown when the deployment SSH hostname suffix is
configured.

Both items appear after a separator below the existing editor/workspace
actions.

## Changes

| File | What |
|---|---|
| `TopBar.tsx` | Added `Open Terminal` and `Copy SSH Command` dropdown
items with separator, `TerminalIcon`/`CopyIcon`, toast on copy |
| `AgentDetail.tsx` | Wired up `getTerminalHref`, `openAppInNewWindow`,
`deploymentSSHConfig` query, and passed new props to TopBar in all 3
render paths |
| `TopBar.stories.tsx` | Added new fields to default story props |
2026-03-03 11:44:39 +00:00
Cian Johnston 517cb0ce73 refactor(webpush): use RequireExperimentWithDevBypass middleware (#22525)
Replace manual experiment checks in web-push handlers with the
`RequireExperimentWithDevBypass` middleware on the route group, matching
the pattern used by OAuth2, Agents, and MCP experiments.

## Changes

- **`coderd/coderd.go`**: Add `RequireExperimentWithDevBypass`
middleware to `/webpush` route group
- **`coderd/webpush.go`**: Remove inline
`api.Experiments.Enabled(codersdk.ExperimentWebPush)` checks from all
three handlers
- **`cli/server.go`**: Gate webpush dispatcher initialization with
`buildinfo.IsDev()` fallback so dev builds always init the real
dispatcher
- **`coderd/webpush_test.go`**: Remove experiment enablement from tests
(dev bypass handles it)

Net effect: -26 lines removed, +5 added.

Created using whatchamacallits (Opus 4.6 Max)
2026-03-03 09:49:04 +00:00
Cian Johnston d787b3cada fix(coderd): fix error handling in deleteUserWebpushSubscription (#22500)
## Summary

`deleteUserWebpushSubscription` in `coderd/webpush.go` had incorrect
error handling that masked database errors as 404 responses.

## Bug

`GetWebpushSubscriptionsByUserID` is a `:many` query — it returns `([],
nil)` when no rows match, never `sql.ErrNoRows`. The previous `if/else
if` chain:

```go
if existing, err := api.Database.GetWebpushSubscriptionsByUserID(ctx, user.ID); err != nil && errors.Is(err, sql.ErrNoRows) {
    // dead code — :many queries never return sql.ErrNoRows
} else if idx := slices.IndexFunc(existing, ...); idx == -1 {
    // real DB errors fall through here, existing is nil, idx is -1 → 404
}
```

Any real database error (connection failure, timeout, authorization
error) fell through to the `else if` branch where `slices.IndexFunc(nil,
...)` returns `-1`, returning 404 "subscription not found" instead of
500.

## Fix

Split into two separate checks so database errors properly return 500:

```go
existing, err := api.Database.GetWebpushSubscriptionsByUserID(ctx, user.ID)
if err != nil {
    // 500
}
if idx := slices.IndexFunc(existing, ...); idx == -1 {
    // 404
}
```

## Testing

Added `TestDeleteWebpushSubscription/database_error_returns_500` which
wraps the DB store to inject an error into
`GetWebpushSubscriptionsByUserID` and asserts the handler returns 500
(not 404).
2026-03-02 21:11:20 +00:00
49aefdd973 chore: update test directions in AGENTS.md (#22490)
Our `AGENTS.md` previously contained this directive:

> When adding tests for new behavior, add new test cases instead of
modifying existing ones. This preserves coverage for the original
behavior and makes it clear what the new test covers.

This leads to inflated diffs and test explosions. Updating it to bias
more towards updating existing tests where applicable.

---------

Co-authored-by: Danielle Maywood <danielle@themaywoods.com>
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2026-03-02 17:07:38 +00:00
Cian Johnston a62f2fbfc4 feat(rbac): add AsChatd subject to replace AsSystemRestricted in chatd (#22487)
Add a new SubjectTypeChatd RBAC subject with minimal permissions:
- Chat: CRUD
- Workspace: Read
- DeploymentConfig: Read

Replace all 10 AsSystemRestricted calls in coderd/chatd/chatd.go:
- Line 890: Use AsChatd instead of AsSystemRestricted for the background
processor context.
- Subscribe() path (5 calls): Remove system escalation entirely; these
run under the authenticated user's context from the HTTP handler.
- processChat path (4 calls): Remove redundant per-call wraps; the
context already carries AsChatd from the processor start.

Add TestAsChatd verifying allowed and denied actions.

Created using Mux (Opus 4.6)
2026-03-02 15:57:04 +00:00
Cian Johnston 0cfa03718e fix(stringutil): operate on runes instead of bytes in Truncate (#22388)
Fixes https://github.com/coder/coder/issues/22375

Updates `stringutil.Truncate` to properly handle multi-byte UTF-8
characters.
Adds tests for multi-byte truncation with word boundary.

Created by Mux using Opus 4.6
2026-02-27 17:46:37 +00:00
Cian Johnston 67da4e8b56 ci: add temporary deploy override (#22378)
Temporary override for deploying `main` to `dev.coder.com`.
2026-02-27 16:32:10 +00:00
Cian Johnston 6336fee3a7 feat: add telemetry for task lifecycle events (#21922)
Relates to https://github.com/coder/internal/issues/1259

Adds new database queries and telemetry collection functions to gather
task lifecycle events (pause/resume cycles, idle time) for analytics.
    
Task events track pause/resume activity, idle duration before pausing,
paused duration, and time from resume to first app status, filtered to
recent activity based on the telemetry snapshot interval.

🤖 Created with Mux (Opus 4.6).
2026-02-24 17:04:42 +00:00
Cian JohnstonandSteven Masley cfdbd5251a chore: add compose alternative to develop.sh (#22157)
Adds a `compose.dev.yml` intended as a pure-Docker alternative to
`develop.sh`.

---------

Co-authored-by: Steven Masley <stevenmasley@gmail.com>
2026-02-19 09:28:52 +00:00
Cian Johnston f8eea54e97 fix(coderd): use BuildReasonTaskAutoPause for task workspaces (#22126)
Relates to https://github.com/coder/internal/issues/1252

When a workspace with a TaskID hits its deadline, use
BuildReasonTaskAutoPause instead of BuildReasonAutostop. This allows
downstream systems to distinguish between regular autostop and task
workspace pauses.

Created by Mux using Opus 4.5.
2026-02-17 15:11:04 +00:00
Cian JohnstonandClaude Opus 4.5 4a3304fc38 feat(cli)!: expire tokens by default (#21783)
## Summary

> NOTE: Calling this out as a breaking change in case existing consumers
of the CLI depend on being able to see expired tokens OR being able to
delete tokens immediately.

Updates the `coder tokens rm` command to immediately expire a token by
ID, preserving the token record for audit trail purposes. Tokens can
still be deleted by passing `--delete`.

## Problem

During an incident on dev.coder.com, operators needed to urgently expire
an API key that was stuck in a hot loop. The only way to do this was via
direct database access:

```sql
UPDATE api_keys SET expires_at = NOW() WHERE id = '...';
```

This is not ideal for operators who may not have direct DB access or
want to avoid manual SQL.

## Solution

This PR adds:

- **API endpoint**: `PUT /api/v2/users/{user}/keys/{keyid}/expire` -
Sets the token's `expires_at` to now
- **SDK method**: `ExpireAPIKey(ctx, userID, keyID)` 
- **Updates CLI**: `coder tokens rm <name|id|token>` now _expires_ by
default. You can still delete by passing the `--delete` flag. The `coder
tokens list` command now also hides expired tokens by default. You can
`--include-expired` if needed to include them.
- **Audit logging**: The expire action is logged with old and new key
states

## Test plan

- Tests cover: owner expiring own token, admin expiring other user's
token, non-admin cannot expire other's token, 404 for non-existent token

Closes #21782

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 13:16:46 +00:00
Cian Johnston 194d79402e chore: remove dbmem comment references (#22056)
👻 The ghost of dbmem managed to live on... until now.
2026-02-12 09:06:33 +00:00
Cian Johnston c2c2b6f16f chore: remove call to taskname.Generate in dbgen (#22040)
I was trying to figure out why `goleak` was complaining about a dangling
http2 connection goroutine in tests. Turns out that `taskname.Generate`
will call out to Anthropic if an API key is set, and we're calling it in
`dbgen`. Modified to use testutil method instead.
2026-02-10 19:16:44 +00:00
Cian Johnston 93b000776f fix(cli): revert #21583 (#22000)
Relates to https://github.com/coder/internal/issues/1217

This reverts commit f799cba395.

@deansheather reported that this breaks ControlMaster.

Investigating alternative fixes to coder/internal#1217
2026-02-09 09:56:33 +00:00
Cian JohnstonandCopilot 25a0c807cb chore(coderd/database/dbfake): add support for provisioner job timestamp control (#21944)
Relates to https://github.com/coder/coder/pull/21922 /
https://github.com/coder/internal/issues/1259

* Adds `dbfake.BuilderOption func(*WorkspaceBuildBuilder)`
* Adds `BuilderOption` methods for setting various provisioner job
related fields on `WorkspaceBuildBuilder`.
* Migrates a number of existing tests that previously dependeded on
provisioner job timing to use these updated methods in the following
packages:
  * `coderd/jobreaper`
  * `coderd/notifications/reports`
  * `enterprise/coderd/schedule`
  * `enterprise/coderd/prebuilds`
  * `scripts/workspace-runtime-audit` 

🤖 Created using Mux (Opus 4.5)

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-06 09:44:40 +00:00
Cian Johnston 91be688e39 chore(coderd/database): remove deprecated db2sdk.List(Lazy)? methods (#21902)
Removes deprecated methods db2sdk.List and db2sdk.ListLazy.
2026-02-03 17:52:07 +00:00
Cian JohnstonandClaude 353ebd9664 feat: add link for viewing raw build logs in workspace and template build jobs (#21727)
* Adds support for parameter `format=text` in the following API routes:
  * `/api/v2/workspaceagents/:id/logs`
  * `/api/v2/workspacebuilds/:id/logs`
  * `/api/v2/templateversions/:id/logs` 
  * `/api/v2/templateversions/:id/dry-run/:id/logs` 

* Adds links to view raw logs on the following pages:
  * Workspace build page
  * Template editor page
  * Template version page

* Refactors existing log formatting in `cli/logs.go` to live in `codersdk`.

🤖 Generated with Claude Opus 4.5, reviewed by me.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-03 09:45:23 +00:00
Cian Johnston 14b4650d6c chore: fix flakiness in TestSSH/StdioExitOnParentDeath (#21792)
Relates to https://github.com/coder/internal/issues/1289
2026-01-30 15:46:38 +00:00
Cian Johnston c2c225052a chore(enterprise/coderd): ensure TestManagedAgentLimit differentiates between tasks and workspaces (#21731)
My previous change to this test did not create another **workspace**
using the template containing `coder_ai_task` resources, meaning that
this test was not actually testing the right thing. This PR addresses
this oversight.
2026-01-28 16:30:56 +00:00
Cian Johnston b1267c458c chore(dogfood/coder): use opus instead of sonnet for claude-code module (#21700) 2026-01-27 12:23:35 +00:00
Cian Johnston 7b44976618 fix(coderd/provisionerdserver): correct managed agent tracking (#21696)
Relates to https://github.com/coder/internal/issues/1282

Updates tracking of managed agents to be predicated instead on the
presence of a related `task_id` instead of the presence of a
`coder_ai_task` resource.
2026-01-27 12:14:52 +00:00
Cian Johnston 612aae2523 chore: replace httpapi.Heartbeat with httpapi.HeartbeatClose (#21676)
Relates to https://github.com/coder/coder/pull/21676

* Replaces all existing usages of `httpapi.Heartbeat` with `httpapi.HeartbeatClose`
* Removes `httpapi.HeartbeatClose`
2026-01-26 12:11:40 +00:00
Cian Johnston 0d21365825 chore: fix failing agent tests with non-default shell (#21671)
* Updates agent tests to write `exit 0` to stdin before closing.
* Updates agent stats tests to detect required stats split out over multiple reports
2026-01-26 09:42:24 +00:00
Cian Johnston fa7baebdd8 fix(coderd): handle rbac.NotAuthorizedError when deleting template (#21645)
Relates to
https://github.com/coder/aibridge/pull/143/changes#r2720659638

We previously had been returning the following when attempting to delete
failed due to lack of permissions.

```
500 Internal error deleting template: unauthorized: rbac: forbidden
```

This PR updates the handler to return our usual 403 forbidden response.
2026-01-23 12:02:46 +00:00
Cian Johnston 365ab0e609 test: bump timeout on TestSSH/StdioExitOnParentDeath (#21630)
Relates to https://github.com/coder/internal/issues/1289

I was able to reproduce the issue locally -- it appears to sometimes
just take 25 seconds to get all of the test dependencies stood up:

```
t.go:111: 2026-01-22 16:39:15.388 [debu]  pubsub: pubsub dialing postgres  network=tcp  address=127.0.0.1:5432  timeout_ms=0 
...
    t.go:111: 2026-01-22 16:39:38.789 [info]  agent.net.tailnet.tcp: accepted connection  src=[fd7a:115c:a1e0:44b1:8901:8f09:e605:d019]:55406  dst=[fd7a:115c:a1e0:4cfd:a892:e4e2:8cad:8534]:1
...
    ssh_test.go:1208: 
                Error Trace:    /Users/cian/src/coder/coder/testutil/chan.go:74
                                                        /Users/cian/src/coder/coder/cli/ssh_test.go:1208
                Error:          SoftTryReceive: context expired
                Test:           TestSSH/StdioExitOnParentDeath
    ssh_test.go:1212: 
```

Hopefully bumping the timeout should fix it.
2026-01-23 10:17:41 +00:00
Cian Johnston f799cba395 fix(cli): allow coder ssh --stdio to exit when parent process dies (#21583)
Relates to https://github.com/coder/internal/issues/1217

Adds a background goroutine in `--stdio` mode to check if the parent PID
is still alive and exit if it is no longer present.

🤖 Implemented using Mux + Claude Opus 4.5, reviewed and refactored by
me.
2026-01-21 14:14:51 +00:00
Cian Johnston 9776dc16bd fix(coderd/database/dbmetrics): fix incorrect query label in GetWorkspaceAgentAndWorkspaceByID (#21576)
Fixes an incorrect label.
2026-01-19 16:25:36 +00:00
Cian Johnston 08343a7a9f perf: reduce number of queries made by /api/v2/workspaceagents/{id} (#21522)
Relates to https://github.com/coder/internal/issues/1214

The `ExtractWorkspaceAgentParam` middleware ends up making 4 database
queries to follow the chain of `WorkspaceAgent` -> `WorkspaceResource`
-> `ProvisionerJob` -> `WorkspaceBuild` -- but then dropping all that
hard work on the floor. The `api.workspaceAgent` handler that references
this middleware then has to do all of that work again, plus one more
query to get the related `User` so we can get the username. This pattern
is also mirrored in `getDatabaseTerminal` but without the middleware.

This PR:
* Adds a new query `GetWorkspaceAgentAndWorkspaceByID` to fetch all
this information at once to avoid the multiple round-trips,
* Updates the existing usage of `GetWorkspaceAgentByID` to this new
query instead,
* Updates `ExtractWorkspaceAgentParam` to also store the workspace in
the request context

Dalibo: [0.63ms](https://explain.dalibo.com/plan/40bb597f3539gc6c)
2026-01-19 12:36:33 +00:00
Cian Johnston d176714f90 chore: increase du interval to 1h in dogfood/coder template (#21555)
Increases the interval of running `du` on `/home/coder` and
`/var/lib/docker` to 1h.
Also decreases the timout to 1m; having `du` run for longer is likely
not great.
2026-01-19 09:57:29 +00:00
Cian Johnston 34c7fe2eaf chore: update agent metadata in WCOC template (#21549)
This PR:
- Removes the host-related agent metadata. It's not particularly useful
and the hosts have dedicated monitoring via Netdata.
- Adds two metdata blocks to expose the sizes of `/home/coder` and
`/var/lib/docker`
2026-01-19 09:07:44 +00:00
Cian Johnston ab126e0f0a feat: improve usability of coder show (#21539)
This PR improves the usability of `coder show`:

- Adds a header with workspace owner/name, latest build status and time
since, and template name / version name.
- Updates `namedWorkspace` to allow looking up by UUID
- Also improves associated `TestShow` to respect context deadlines.
2026-01-16 15:45:33 +00:00
Cian Johnston ad23ea3561 chore: remove unused ExtractWorkspaceAndAgentParam (#21537)
While investigating https://github.com/coder/internal/issues/1214 I
noticed that `ExtractWorkspaceAndAgentParam` appeared to be unused
outside of tests.
2026-01-16 15:11:10 +00:00
Cian Johnston 3a62a8e70e chore: improve healthcheck timeout message (#21520)
Relates to https://github.com/coder/internal/issues/272

This flake has been persisting for a while, and unfortunately there's no
detail on which healthcheck in particular is holding things up.

This PR adds a concurrency-safe `healthcheck.Progress` and wires it
through `healthcheck.Run`. If the healthcheck times out, it will provide
information on which healthchecks are completed / running, and how long
they took / are still taking.

🤖 Claude Opus 4.5 completed the first round of this implementation,
which I then refactored.
2026-01-15 16:37:05 +00:00
Cian Johnston 5073493850 feat(coderd/database/dbmetrics): add query_counts_total metric (#21506)
Adds a new Prometheus metric `coderd_db_query_counts_total` that tracks
the total number of queries by route, method, and query name. This is
aimed at helping us track down potential optimization candidates for
HTTP handlers that may trigger a number of queries. It is expected to be
used alongside `coderd_api_requests_processed_total` for correlation.

Depends upon new middleware introduced in
https://github.com/coder/coder/pull/21498

Relates to https://github.com/coder/internal/issues/1214
2026-01-15 10:58:56 +00:00
Cian Johnston 32354261d3 chore(coderd/httpmw): extract HTTPRoute middleware (#21498)
Extracts part of the prometheus middleware that stores the route
information in the request context into its own middleware. Also adds
request method information to context.

Relates to https://github.com/coder/internal/issues/1214
2026-01-15 10:26:50 +00:00
Cian JohnstonandDean Sheather 8dd7d8b882 chore: clean up coder build directory on shutdown (#21490)
Adds a step to delete the `build/` directory inside the Coder repo on
shutdown.

---------

Co-authored-by: Dean Sheather <dean@deansheather.com>
2026-01-13 12:45:50 +00:00
Cian Johnston 64e7a77983 feat: add user_agent to loggermw (#21485)
Adds the `user_agent` field to `httpmw/loggermw`.
2026-01-13 10:50:01 +00:00
Cian Johnston 2b448c7178 feat(cli): enrich user-agent header for client requests (#21483)
Adds the following information to CLI User-Agent headers to aid
deployment administrators in troubleshooting where requests are coming
from.

Before: `Go-http-client/1.1`
After: `coder-cli/v2.34.5 (linux/amd64; coder whoami)`

🤖 These changes were generated by Claude Sonnet 4.5 but reviewed and
edited manually by me.
2026-01-12 17:46:05 +00:00
Cian Johnston b116d22c5f chore: manage tool versions in go.mod (#21455)
Go 1.24 adds [tool
dependencies](https://go.dev/doc/modules/managing-dependencies#tools).
This allows us to track versions of tools in our `go.mod` instead of
sprinkling various `go run` commands throughout our codebase.

NOTE: there are still various hard-coded `go install` commands in our
dogfood Dockerfile. As that list is likely severely outdated, will leave
that for a separate PR.
2026-01-08 16:25:28 +00:00
Cian JohnstonandSteven Masley 0f446f99dd feat(cli): add logs cmd (#21430)
This PR adds a command to view the provisioner and agent logs for a
given workspace.
Note: I did investigate using the existing `cliui` methods to tail the
logs but they are tailored to a very specific use-case.

Other changes:
- Adds `Agents` to `dbfake.WorkspaceResponse`
- Adds methods to generate provisioner and agent logs in `dbgen`

---------

Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
2026-01-08 09:58:10 +00:00
Cian Johnston 6bd2d1c85f chore(cli): seed healthcheck cache in TestSupportBundle (#21436)
Fixes https://github.com/coder/internal/issues/272

This test periodically fails due to the healthcheck timing out.
The problem is compounded due to the fact that we stand up a new
coderdtest instance for each test.

This PR does the following:
* Updates the subtests to share a single `coderdtest` instance.
* Hits the `/debug/health` endpoint before completing the setup phase so
that the result is cached.

This will not completely remove the issue, as the healthcheck could
still fail due to test-infrastructure-related issues. In this case we
may decide to add a retry in this 'seed' function.
2026-01-07 08:47:31 +00:00
Cian Johnston 172cd13b24 fix: restore /tmp/.coder-startup-script.done in dogfood template (#21419) 2026-01-05 16:12:35 +00:00
Cian Johnston 7a259ffd39 feat(dogfood): use coder exp sync to synchronize scripts (#21384)
Updates the `coder` template to use `coder exp sync` to synchronize `coder_script` startup dependencies.
2025-12-29 11:00:36 +00:00
Cian Johnston 1de952b556 fix(site): allow updating workspace in TaskPage (#21316)
Relates to #20925 

This PR modifies TaskPage to update an outdated workspace instead of
starting it. Before, starting an outdated workspace where the template
required the active version would fail with the error "cannot use
non-active version: rbac: forbidden".

For the case of a dormant workspace, I deemed it safe enough to simply
unset dormancy on an attempted start (ref:
https://github.com/coder/coder/pull/21306). However, automatically
updating a workspace is a more risky option, so I instead elected to
give the user the option of updating their workspace using the existing
tooltip.


**Note:** I made a change to the `WorkspaceOutdatedTooltip` components
to allow it to have children so that the tooltip could trigger over a
wider element instead of just the info icon.

```
<🤖 AI Disclaimer>I got some help from Gemini 3 Flash in "Ask" mode.</🤖 AI Disclaimer>
```
2025-12-19 11:33:07 +00:00
Cian Johnston 8248fa3b84 fix(coderd): wake dormant workspace when attempting to start it (#21306)
Relates to #20925

This PR modifies the `postWorkspaceBuild` handler to automatically unset
dormancy on a workspace when a start transition is requested.
Previously, the client was responsible for unsetting the dormancy on the
workspace prior to posting a workspace build.
2025-12-18 10:35:04 +00:00
Cian Johnston f1b930b190 chore(enterprise): increase coverage of TestWorkspaceBuild (#21304)
Relates to #20925 
This PR expands the test coverage of `enterprise/coderd/TestWorkspaceBuild` to also exercise the `postWorkspaceBuilds` handler. Previously, it only exercised the `createWorkspace` handler.
2025-12-17 17:28:38 +00:00
Cian Johnston 35b9df86b3 chore(docs): document preset description and icon fields (#20705)
Closes https://github.com/coder/coder/issues/20599

Generated by Claude Code, reviewed by me.
2025-11-19 10:02:43 -06:00
Cian Johnston f59763968f ci(.github/workflows/traiage.yaml): adjust TASK_PROMPT (#20733)
Adjusts instructions for the trAIage workflow to balance autonomy and
correctness.
2025-11-12 11:14:20 +00:00
Cian JohnstonandBen Potter b6935c3528 chore(docs/ai-coder): add migration guide for provider version 2.13.0 (#20426)
Closes https://github.com/coder/internal/issues/1080

---------

Co-authored-by: Ben Potter <ben@coder.com>
2025-11-11 09:07:41 +00:00
Cian Johnston 3819f33693 ci(.github/workflows/traiage.yaml): use create-task-action (#20673)
Updates the existing workflow to use the action defined in
coder/create-task-action.
2025-11-10 13:59:42 +00:00
Cian JohnstonandDanny Kopping 81c3375670 chore: update Go to 1.24.10 (#20684)
Signed-off-by: Danny Kopping <danny@coder.com>
Co-authored-by: Danny Kopping <danny@coder.com>
2025-11-10 09:09:44 +00:00
Cian Johnston 7dc75637a1 fix(examples/templates/tasks-docker): support coder/claude-code 4.0.0 (#20420)
Relates to https://github.com/coder/internal/issues/1065
Essentially the same steps as https://github.com/coder/registry/pull/497
2025-11-06 16:12:21 +00:00
Cian Johnston 2cec1dbbfa chore: update coder/dogfood template to reference coder_task.prompt (#20416)
Relates to https://github.com/coder/internal/issues/1065

Updates the coder/dogfood template to reference new Task features in
provider version ~2.12.0~ 2.13.0:
- Adds a `coder_ai_task` resource and a `coder_task` data source
- Passes `coder_task.me.prompt` into Claude Code module
- Updates Claude Code module to 4.0.0 (ref:
https://github.com/coder/registry/pull/488)
- Removes "AI Prompt" parameter

Update: to avoid a cycle that only appears to occur when using a
`count`, leveraging a data source (ref:
https://github.com/coder/terraform-provider-coder/pull/460)
2025-11-06 15:00:56 +00:00
Cian Johnston 34f6e72879 feat(coderd): add lookup task by name in httpmw.TaskParam (#20647)
* Adds a `GetTaskByOwnerIDAndName` query
* Updates `httpmw.TaskParam` to fall back to task name if no task by
UUID found.
* Updates the `TaskByIdentifier` used in `cli/` to use direct lookup instead of searching.
2025-11-05 14:28:34 +00:00