mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
9ddfafe2b174f55d50fb8e0df8a200b4103a4d2f
14301
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ddfafe2b1 | feat: add chat ACL database foundation (#25080) | ||
|
|
507ece3bc4 |
docs: Fix the display of the tab block in External Workspaces (#25341)
Fixes DOCS-169 <!-- If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. --> |
||
|
|
15c958fea2 |
fix(testutil): ensure FakeSink does not swallow logs (#25185)
`FakeSink` was silently capturing log entries without forwarding them to `testing.TB.Log`. This made debugging test failures harder because logs were invisible in `go test -v` output. Store `testing.TB` in `FakeSink` and call `t.Log` on each entry, guarded by a check to avoid logging after the test has finished. Split out from #25012. > 🤖 Generated with [Coder Agents](https://coder.com) |
||
|
|
132fa87bf3 |
fix: only embed Azure roots on darwin (#25312)
Partially reverts #25136 for non-darwin platforms. In general we want to avoid pinning trust roots to embedded Certs, since that limits operational flexibility. If Azure changes CAs, operators should, at most, be able to update the OS trust store to keep Coder working correctly. Embedding roots means we need to upgrade the Coder binary. Since Coder Server on macOS is not really supported for production use, embedding only in that case to ease development and testing is OK. |
||
|
|
e37bf4f7be |
ci: bump paralleltestctx to v0.0.2 (#25323)
## Summary - bump `github.com/coder/paralleltestctx` from v0.0.1 to v0.0.2 - pick up the latest paralleltestctx timeout-context detection improvements in `go tool ... paralleltestctx` runs |
||
|
|
841b777ccd | feat: add ai_providers table, queries, dbauthz, audit, RBAC (#24892) | ||
|
|
acf57b3b35 |
feat(site): add legacy auto sync helper and tritan cleanup (#25180)
## Summary - Add `legacyAutoToSync` to map legacy auto-family theme preferences to light and dark sync pairs. - Expand colorblind theme tests for legacy auto-family handling. - Move tritan success and git-added surfaces onto the sky-blue palette in theme roles and CSS variables. ## Dependencies - None. This can merge independently before the dropdown work. ## Validation - `pnpm -C site exec vitest run --project=unit src/theme/colorblind.test.ts` - `pnpm -C site lint:types` - Pre-commit hook passed on the branch commit. |
||
|
|
25a803221e | feat: add shell tool display mode preference (#25029) | ||
|
|
3a070a83dd |
fix(site/src/pages/AgentsPage): theme diff changed-line backgrounds (#25179)
## Summary - Update AgentsPage diff viewer CSS so changed lines use theme-aware git added and deleted surfaces. - Add unit coverage for the changed-line CSS variables and line-type selectors. ## Dependencies - None. This is independent of the theme mode API and dropdown stack. ## Validation - `pnpm -C site exec vitest run --project=unit src/pages/AgentsPage/components/ChatElements/tools/utils.test.ts` - Pre-commit hook passed on the branch commit. |
||
|
|
da2fa082bb |
fix(coderd/httpapi): CloseRead on test conns to ensure pings pong (#25184)
The `websocketPair` test helper was not calling `CloseRead` on either side of the connection. Without `CloseRead`, the websocket library does not process control frames (ping/pong), so the heartbeat tests were passing only because no pings had yet failed, not because pings were actually succeeding. Add `CloseRead` on both the client and server connections so that pong frames are delivered in response to pings. Split out from #25012. > 🤖 Generated with [Coder Agents](https://coder.com) |
||
|
|
f3e90b334d |
fix(cli): show sync wait dependencies (#25089)
## Problem `coder exp sync want` and `coder exp sync start` both printed generic success messages, which hid the dependency units involved in startup coordination. Before, declaring dependencies with `sync want` printed: ```text Success ``` Before, `sync start` printed while waiting, then finished with another generic success message: ```text Waiting for dependencies of unit 'test-unit' to be satisfied... Success ``` ## Solution Print the dependency units in both cases, using wording that matches where the command is in the lifecycle. After, `sync want` prints the dependencies it declared for the unit: ```text Unit "test-unit" declared dependencies: [dep-unit] ``` After, `sync start` enumerates the dependencies while it is waiting, then prints the same dependencies after the unit starts executing: ```text Unit "test-unit" is waiting for dependencies to be satisfied: [dep-unit, dep-unit-2] Unit "test-unit" finished waiting for dependencies: [dep-unit, dep-unit-2] ``` The sync golden tests now cover the updated output, including multiple dependencies for `sync start`. |
||
|
|
cb37047dce |
feat: dedicated /prompts endpoint for chat history cycle (#25083)
Follow-up to #25004. The merged change cycles only through messages
already loaded in the in-memory chat store (page size 50). Long chats
and chats whose oldest turns have rolled out of the page lose access to
their earlier prompts in the composer's up/down arrow cycle. This PR
adds a dedicated server endpoint that returns the full prompt history,
newest first, and rewires the composer to use it.
## What changed
### Endpoint
`GET /api/experimental/chats/{chat}/prompts?limit=N`
```go
type ChatPrompt struct { ID int64; Text string }
type ChatPromptsResponse struct { Prompts []ChatPrompt }
```
- `limit`: `0..2000`. `0` (the default) is treated as the server-side
default of 500; out-of-range values return `400`. Negative values are
rejected by the SDK's `PositiveInt32` parser before reaching the
handler.
- Auth: parent-chat read in `dbauthz`, mirroring
`GetChatMessagesByChatID`.
- The SQL filters `role='user'`, `deleted=false`, `visibility IN
('user','both')`, guards the lateral with `jsonb_typeof(content) =
'array'` so legacy V0 scalar-string rows are silently skipped, then
unrolls `content` JSONB with `WITH ORDINALITY` and concatenates only
`type='text'` parts in original order via `string_agg(... ORDER BY
ordinality)`. Messages whose joined text is whitespace-only are dropped
via `HAVING ... ~ '\S'` so cycling never lands on a blank entry.
### Partial index (migration `000494`)
```sql
CREATE INDEX idx_chat_messages_user_prompts
ON chat_messages (chat_id, id DESC)
WHERE deleted = false
AND role = 'user'
AND visibility IN ('user', 'both');
```
The partial WHERE matches the query's filter exactly and the key order
matches `ORDER BY id DESC`, so the planner gets both the filter and the
ordering from the index without a sort step.
`EXPLAIN ANALYZE` on a synthetic 51-chat × 5,000-message dataset (≈260k
rows, 10k user prompts in the target chat, `random_page_cost=1.1`):
| | Plan | Buffers hit | Time |
|---|---|---|---|
| Without index | `Index Scan Backward using chat_messages_pkey`,
**250,848 rows removed by filter** | 6,683 | 32.4 ms |
| With index | `Index Scan using idx_chat_messages_user_prompts`, no
filter | 38 | 1.3 ms |
≈25× faster, 175× fewer buffer hits.
### Frontend
- `chatPromptsKey` / `chatPromptsQuery` factories in
`site/src/api/queries/chats.ts` (`staleTime: 30s`, `enabled: chatId !==
""`, asks the server for 500 prompts).
- `ChatPageContent.tsx` replaces the in-memory derivation with
`useQuery(chatPromptsQuery(chatId ?? ""))`. The composer's existing
`cycleHistorySnapshotRef` anchors the in-flight cycle so a refetch
arriving mid-cycle cannot shift the indexed prompt out from under the
user.
- `getEditableUserMessagePayload` now concatenates user-message text
parts verbatim, mirroring the server's `string_agg(part->>'text', ''
ORDER BY ordinality)`, instead of routing through the streaming-oriented
`parseMessageContent` / `appendText` pipeline (which drops
whitespace-only chunks — correct for assistant streams, wrong for a
user's persisted message). This keeps the cycle and the edit path in
agreement on the same message. File blocks are still pulled separately
via
`parseMessageContent(...).blocks.filter(isEditableUserMessageFileBlock)`.
- Cache invalidation in `createChatMessage.onSuccess`,
`editChatMessage.onSettled`, and `useChatStore.upsertCacheMessages`
(only when an upserted message has `role === "user"`).
- Page-level stories pre-seed `chatPromptsKey(CHAT_ID)` from the same
`messagesData` to keep them offline.
## Tests
- New `TestGetChatUserPrompts` in `coderd/exp_chats_test.go` with five
subtests:
- `NewestFirstFiltering` — multi-part concatenation, non-text parts
skipped, whitespace-only filtered, soft-deleted excluded, `model`-only
visibility excluded, assistant-role excluded by `cm.role = 'user'`,
legacy V0 scalar row silently excluded by the `jsonb_typeof` guard,
ordering newest first.
- `LimitClampsResults` — explicit `limit=2` returns the two newest
prompts.
- `InvalidLimitRejected` — `limit=5000` is `400 Bad Request`.
- `NotFoundForOtherUsers` — a separate user in the same org gets `404`,
not the prompts.
- `EmptyResultIsJSONArray` — zero-message chat and assistant-only chat
both return `Prompts: []` (non-nil, empty).
- New unit test in `messageParsing.test.ts` asserting that
`getEditableUserMessagePayload(["hello", " ", "world"])` returns `"hello
world"`, locking in the agreement with the SQL `string_agg`.
- `dbauthz_test.go` adds the
`MethodTestSuite.TestChats/GetChatUserPromptsByChatID` entry, asserting
parent-chat `policy.ActionRead`.
- `pnpm test src/pages/AgentsPage` — 1159 passed, 2 skipped.
- `make gen` produces no diff.
## Manual verification
Seeded a dev chat with Claude Sonnet 4.6 via the aibridge Anthropic
provider and posted 20 user prompts end-to-end. Verified that the
`/prompts` endpoint returns 20 rows newest-first, that `limit=10` clamps
correctly, that `limit=0` uses the server default of 500, and that the
up/down keyboard cycle in the composer walks the same sequence (and
reverses correctly back to the empty draft).
## Out of scope
- Cross-chat history.
- Per-user opt-out for the cycle.
- File-reference / attachment cycling — the cycle continues to reproduce
plain text only, by design.
<details>
<summary>Implementation plan</summary>
# CODAGT-319 Follow-up — Dedicated `/prompts` endpoint
## Context
The merged feature ([#25004](https://github.com/coder/coder/pull/25004)
/ [
|
||
|
|
f71bccf53f |
ci(.github/actions/setup-node): verify active Node version (#25143)
Updates the shared setup-node composite action to current Node 24 based releases of `pnpm/action-setup` and `actions/setup-node`. This avoids the deprecated Node 20 action runtime seen in CODAGT-178 while keeping the third-party actions pinned by SHA. Adds an explicit post-setup check that fails inside Setup Node when `node --version` is not `v22.19.0`, so self-hosted runner/toolcache mismatches are surfaced before `pnpm install` reports a dependency engine error. Closes https://github.com/coder/internal/issues/1457 Generated by Coder Agents. |
||
|
|
f7d1ecaece | refactor(site): inline single-use class string constant in AgentSetupNotice (#25086) | ||
|
|
581f3bdd14 |
fix(coderd/httpapi): stop writing websocket frames to ResponseRecorder in test (#25284)
The `mockEventSenderWrite` function in `newOneWayWriter()` wrote WebSocket frame data to both the `net.Pipe` and the `httptest.ResponseRecorder`. After `websocket.Accept()` calls `WriteHeader(101)`, the recorder rejects body writes with `"response status code does not allow body"`. When `HeartbeatClose` sends a ping, the control frame flush routes through the recorder, producing an ERROR-level log that `slogtest` catches as a test failure. Removed the `recorder.Write(b)` call from the write function. The recorder is only needed for header/status inspection; WebSocket frame data should only go through the `net.Pipe`. Closes https://github.com/coder/internal/issues/1521 > 🤖 Generated by Coder Agents |
||
|
|
024132e8a4 |
feat: add theme_mode, theme_light, theme_dark to UserAppearanceSettings (#25076)
Part 1: Backend portion of a change broken into 2 PRs. Part 2: #25077 Adds three new UserAppearanceSettings fields (theme_mode, theme_light, theme_dark) on top of the existing theme_preference and terminal_font. Replaces GetUserThemePreference and GetUserTerminalFont with a single GetUserAppearanceSettings aggregate query. The PUT handler is wrapped in db.InTx so sync-mode's mode + slot writes can never half-apply. |
||
|
|
d147dd3bdd |
feat(site/src/pages/AgentsPage/components): show workspace quota in usage indicator (#25168)
This updates the Agents sidebar usage indicator to surface workspace quota alongside AI spend limits. When both signals are active, the compact trigger renders stacked bars in the same order as the dropdown instead of collapsing them into a single percent. The dropdown still shows the full labels, percentages, and details for each usage section, and Storybook coverage now exercises the combined sidebar state. <img width="315" height="261" alt="image" src="https://github.com/user-attachments/assets/e5cfc276-2cc0-4dc9-9400-6d1b829e75e2" /> <img width="320" height="243" alt="image" src="https://github.com/user-attachments/assets/506ae8ad-3d93-4857-9cdb-b3cf4142772d" /> <img width="314" height="353" alt="image" src="https://github.com/user-attachments/assets/5af3644f-f155-43a4-bae9-91b33a0a4333" /> <img width="322" height="349" alt="image" src="https://github.com/user-attachments/assets/9ae4ae55-55aa-4a2f-856e-f462793f389e" /> Relates to CODAGT-197 |
||
|
|
a35f71cd8a |
fix(coderd/x/chatd): retry HTTP/2 stream resets (#25170)
Mid-stream HTTP/2 peer resets from LLM providers can arrive after a 200 streaming response has already emitted provisional parts. Previously those resets fell through as generic non-retryable errors because `stream ID` messages did not match retryable transport signals, and stream IDs could be misread as HTTP statuses. Classify retryable HTTP/2 RST_STREAM codes as transient timeout failures, ignore stream IDs during status extraction, and keep the existing `retry` event as the rollback boundary for provisional message parts so replacement attempts do not replay failed-attempt output. Closes CODAGT-382 |
||
|
|
2943bf5f21 | fix(site): use ExternalImage for icon URLs (#25315) | ||
|
|
ef1093d0dd | fix(site): hide sticky metadata user messages (#25316) | ||
|
|
7aaa8485db |
docs: update screenshot to point to generic URL (#25314)
At present, the docs point to an internal URL, so I'm updating the screenshot to point to a ficticious address. Fixes DOCS-59 |
||
|
|
d1a471e29e |
fix(coderd/x/chatd): retune subagent selection guidance (#25311)
> Mux working on behalf of Mike. ## Summary - retune chatd subagent guidance to prefer `general` for substantial delegated work, including read-only synthesis and planning support - narrow `explore` guidance to repository-local code lookup and bounded tracing - add regression tests for planning, spawn tool, and Plan Mode guidance text ## Tests - `go test ./coderd/x/chatd -run 'Test(DefaultSystemPromptPlanningGuidance_SteersSubagentSelection|SpawnAgent_DescriptionSteersGeneralForSubstantialResearch|SpawnAgent_PlanModeDescriptionOmitsComputerUse|PlanningOverlaySubagentGuidance_UsesPlanModeSafeDescriptions|ExploreSubagentIsReadOnly)$'` - `make lint` - `make test TEST_PACKAGES=./coderd/x/chatd RUN=Guidance && make test TEST_PACKAGES=./coderd/x/chatd RUN=Description` - pre-commit hook during `git commit` |
||
|
|
341051ceee | fix: exclude service accounts from license seat count (#24401) | ||
|
|
e0be9bf213 |
feat: surface missing coder_secret requirements on resolve-autostart (#25081)
Adds `dynamicparameters.EvaluateSecretMismatch` as a shared helper on top of the existing renderer, then wires it into the resolve-autostart handler so the UI can surface unsatisfied `coder_secret` requirements in a template alongside parameter mismatch for autostart. The lifecycle executor changes will land in a follow-up that depend on this helper. The UI changes that consume the new `secret_mismatch` field is also a follow-up. Generated with assistance from Coder Agents. |
||
|
|
0f505aa4da |
chore: unhide flag to force unix filepaths in config-ssh (#25142)
Docs now include this flag. This flag is now also viewable in linux/mac despite it effectively being a `no-op`. Closes https://github.com/coder/coder/issues/24205 |
||
|
|
38f586107d | refactor: remove agents TUI (#25190) | ||
|
|
660fa9478f | style(site): use shorthand for boolean JSX props (#25096) | ||
|
|
49c6191bbe |
fix(coderd/azureidentity): add Azure IMDS G2 chain certificates (#25243)
Azure IMDS attested data signatures can now chain through Microsoft TLS G2 RSA CA OCSP intermediates, then through the cross-signed Microsoft TLS RSA Root G2 certificate, before reaching DigiCert Global Root G2. coderd did not bundle the new G2 OCSP intermediates or the cross-signed Microsoft TLS RSA Root G2 bridge certificate, so it could fail to build a trusted chain for affected IMDS signatures. Related to: https://linear.app/codercom/issue/PLAT-205/bug-azure-instance-identity-verification-is-broken |
||
|
|
7fe4d97fd0 | fix(site): align streaming thinking spacing (#25291) | ||
|
|
b9b8d763e3 |
refactor(site/src/pages/AgentsPage): break AgentChatPage circular dep (#25287)
`AgentChatPageView.tsx` imported `getPersistedSidebarTabId` / `savePersistedSidebarTabId` from `AgentChatPage.tsx`, which already imports `AgentChatPageView`, closing a cycle that `pnpm run lint:circular-deps` reports but doesn't fail on (dpdm defaults to exit code 0; the script is missing `--exit-code circular:1`). Move the three sidebar-tab localStorage helpers and the key prefix into `utils/sidebarTabStorage.ts` alongside `draftStorage.ts` and the other per-chat storage modules. Pure code move, no behavior change. After this change, `pnpm run lint:circular-deps` reports zero cycles. --------- Signed-off-by: Thomas Kosiewski <tk@coder.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
36200b625e | fix: fix flaky storybook test (#25272) | ||
|
|
5040ab6fca |
feat: filter chats by diff URL via the q search parameter (#24970)
Adds a `diff_url:` term to the `q` search parameter on `GET /api/experimental/chats` so callers can look up the chat associated with a particular pull request, merge request, or any other URL persisted on the chat's diff status. ``` q=diff_url:"https://github.com/coder/coder/pull/123" ``` Match is case-insensitive. When the URL lives on a delegated sub-agent's diff status, the parent chat is returned so the relationship surfaces from a single lookup. <details> <summary>Design notes</summary> - **Forge-agnostic.** Reuses the existing `chat_diff_statuses.url` column rather than introducing a `pr:` vocabulary, since the SDK already documents the URL as "may point to a pull request or a branch page depending on whether a PR has been opened." Works for GitHub PRs, GitLab MRs, branch pages, etc. - **Composes with `archived:`.** The two terms can be combined: `q=archived:true diff_url:"..."`. - **Case handling.** The parser used to lowercase the entire `q` string up front, which would mangle URL path segments. Switched to lowercasing only the field key inside `searchTerms` (already happens there) and keeping the value as the caller typed it. The SQL comparison lowercases on both sides. - **Validation.** `diff_url` must be a syntactically valid HTTP(S) URL with a non-empty host. No forge-specific validation. - **Index.** Adds `idx_chat_diff_statuses_url_lower` on `LOWER(url)` so the lookup is cheap even on large datasets. - **Sub-agent fan-in.** `EXISTS` clause matches when the URL lives on the chat itself or any chat with `root_chat_id` equal to the chat's id, so a delegated sub-agent's PR pulls in its parent. - **Deferred.** Sentinels like `pr:any` / `pr:none` and a forge-agnostic state filter (`diff_state:open|merged|closed`) were intentionally left out of this change. They couple cleanly to a second forge or a clearer product call, and shipping them now would lock in vocabulary we may want to revisit. </details> ## Tests - `coderd/searchquery`: parser tests for valid URLs, case handling (key insensitive, value preserved), composition with `archived:`, and validation errors (non-HTTP scheme, missing host, malformed URL). - `coderd/exp_chats_test.go`: end-to-end coverage hitting `ListChats`. Verifies a root chat matches its own URL, a parent chat surfaces when only a sub-agent has the URL, lookups are case-insensitive, non-matching URLs return empty, and invalid URLs return `400`. --- _This PR was authored by a Coder Agent on behalf of @kylecarbs._ |
||
|
|
8eb7051987 |
fix(scripts/ironbank): update base image to UBI9 and remove urllib3 (CVE-2026-44431) (#25217)
The IronBank Dockerfile used UBI8-minimal:8.7 as its base image. IronBank has migrated images to UBI9 base, and the bundled urllib3 1.26.5 in the image triggers CVE-2026-44431 (sensitive headers leaked on cross-origin redirects via the low-level API). This updates the base image from UBI8-minimal to UBI9-minimal and explicitly removes python3-urllib3 after package installation. Coder is a Go binary and does not invoke Python at runtime, so urllib3 is unused. Refs [ENT-4](https://linear.app/codercom/issue/ENT-4/ironbank-v23111-update-urllib3-from-1265-to-fix-cve-2026-44431), [ENT-51](https://linear.app/codercom/issue/ENT-51/ironbank-main-update-base-image-urllib3-cve-2026-44431), [CVE-2026-44431](https://nvd.nist.gov/vuln/detail/CVE-2026-44431) > Generated by Coder Agents <details><summary>Decision log</summary> - **Base image**: Moved from `ubi8-minimal:8.7` to `ubi9-minimal:9.6` to align with IronBank's UBI9 migration and reduce overall vulnerability surface. - **urllib3 removal**: Added explicit `microdnf remove python3-urllib3` with error suppression (`|| true`) so the build succeeds whether or not the package is present in the base image. This handles both the minimal and full UBI9 base image variants that IronBank may use. - **Crypto policies**: RHEL 9 uses the same `/etc/crypto-policies/back-ends/*.config` paths as RHEL 8; no changes needed. - **Build script**: Updated the `registry.access.redhat.com` override from `ubi8/ubi-minimal:8.7` to `ubi9/ubi-minimal:9.6` for local builds. </details> |
||
|
|
1a1f06aa79 |
fix: verify PKCS7 signature on Azure instance identity tokens (#25286)
Migrates Azure instance identity verification from `go.mozilla.org/pkcs7` and `github.com/fullsailor/pkcs7` to `github.com/smallstep/pkcs7`, using `VerifyWithChainAtTime` to validate both the PKCS7 signature and the certificate chain in one call. The previous code only verified the signer certificate against a set of intermediates/roots but did not verify that the PKCS7 signature itself covered the content, meaning tampered payloads could be accepted. The `Options` struct is restructured to accept `Roots`, `Intermediates`, and `CurrentTime` as explicit fields instead of embedding `x509.VerifyOptions`. The test helper `NewAzureInstanceIdentity` now builds a realistic 3-level certificate chain (Root CA -> Intermediate CA -> Signing Cert) matching real Azure trust hierarchy. New tests (`TestValidate_TamperedContent`, `TestValidate_UntrustedCertWithValidSignature`) confirm tampered and untrusted envelopes are rejected. Addresses GHSA-6x44-w3xg-hqqf. > [!NOTE] > This PR was authored by Coder Agents. <details> <summary>Implementation Plan</summary> ### Files Changed | File | Summary | |------|---------| | `coderd/azureidentity/azureidentity.go` | Replace `signer.Verify()` with `VerifyWithChainAtTime`; restructure `Options` struct; add `ParseCertificates()` helper | | `coderd/azureidentity/azureidentity_test.go` | Add `testCertChain` builder, tampered-content and untrusted-cert tests; update existing tests for new `Options` API | | `coderd/coderd.go` | Change `AzureCertificates` field from `x509.VerifyOptions` to `azureidentity.Options` | | `coderd/workspaceresourceauth.go` | Pass `api.AzureCertificates` directly instead of wrapping | | `coderd/coderdtest/coderdtest.go` | Migrate to `smallstep/pkcs7`; build 3-level cert chain in test helper | | `go.mod` / `go.sum` | Add `github.com/smallstep/pkcs7`; remove `fullsailor/pkcs7` and `go.mozilla.org/pkcs7` | </details> |
||
|
|
b52c0bdb56 | fix(site/src/pages/AgentsPage/components): unify live thinking spacing and sizing (#25192) | ||
|
|
57b11d405f |
fix(coderd): harden Azure identity certificate fetch (#25274)
Security improvements: - Restrict cert fetches to a host+port allowlist (Microsoft and DigiCert on 80/443). - Route requests through a dedicated `http.Client` that resolves the host once and dials the validated IP directly, preventing DNS rebinding. - Reject loopback, private (RFC 1918 / IPv6 ULA), link-local, multicast, unspecified, CGNAT, benchmarking, and IPv4-mapped IPv6 addresses. - Cap the certificate response body at 1 MiB. - Log the underlying error via slog and return a generic detail to the caller to prevent information disclosure. |
||
|
|
9400eaa957 |
revert(coderd): "Merge commit from fork" (#25273)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
5b87d7b74f |
feat(agent/agentcontextconfig): discover skills from ~/.coder/skills (#25271)
The default skills lookup only scanned the project-relative .agents/skills directory, so personal skills had to be repeated per project or wired in via CODER_AGENT_EXP_SKILLS_DIRS. Now the default is the comma-separated list ~/.coder/skills,.agents/skills, which lets discoverSkills's existing first-occurrence-wins policy prefer home-scoped skills over project ones with the same name. The change is additive when ~/.coder/skills is absent (missing directories are silently skipped in discoverSkills) and unaffects users who set the env var explicitly. Closes CODAGT-403 |
||
|
|
fb3aef1883 |
Merge commit from fork
* fix(coderd): Harden Azure identity certificate fetch - Restrict cert fetches to a host+port allowlist (Microsoft and DigiCert on 80/443). - Route requests through a dedicated `http.Client` that resolves the host once and dials the validated IP directly. - Reject loopback, private (RFC 1918 / IPv6 ULA), link-local, multicast, unspecified, CGNAT, benchmarking, and IPv4-mapped IPv6 addresses. - Cap the certificate response body at 1 MiB. - Log the underlying error via slog and return a generic detail to the caller. - Add unit tests for the URL allowlist, IP classification, and dialer. * fix(coderd/azureidentity): add IPv6 special-use ranges to SSRF blocklist The extraBlockedNetworks list only contained IPv4 CIDRs. Add IPv6 equivalents that Go's stdlib classification methods do not cover: - 64:ff9b:1::/48 RFC 8215 NAT64 translation - 100::/64 RFC 6666 discard-only - 2001:2::/48 RFC 5180 benchmarking - 2001:db8::/32 RFC 3849 documentation IPv6 ranges already handled by stdlib (unchanged): - ::1/128 (IsLoopback) - fc00::/7 (IsPrivate, ULA) - fe80::/10 (IsLinkLocalUnicast) - ff00::/8 (IsMulticast) - ::/128 (IsUnspecified) |
||
|
|
5be959e111 | fix(agent): retry devcontainer sub-agent rejection test (#25187) | ||
|
|
8955599bd0 |
fix: bump sqlc fork to v1.31.1 merge, strip pg_dump meta-commands (#25105)
Closes https://github.com/coder/internal/issues/965 Recent `pg_dump` patch releases (13.22+ / 14.19+ / 15.14+ / 16.10+ / 17.6+) emit `\restrict` / `\unrestrict` psql meta-commands at the head and tail of schema dumps. These broke both `sqlc` and our `scripts/migrate-test` schema-equality check. PR #19696 worked around it by pinning `pg_dump` to a Docker image. This change unpins the workaround now that `sqlc` handles the meta-commands: * Bumps the coder/sqlc fork pin to [`337309b` on coder/sqlc:main](https://github.com/coder/sqlc/commit/337309bfb9524f38466a5090e310040fc7af0203), the merge of upstream v1.31.1 (coder/sqlc#6). v1.31.1 includes [sqlc-dev/sqlc#4390](https://github.com/sqlc-dev/sqlc/pull/4390), the upstream `\restrict` / `\unrestrict` parser fix. Updated in three places that pin the fork SHA: `flake.nix` (`sqlc-custom`), `.github/actions/setup-sqlc/action.yaml`, and the `dogfood/coder/ubuntu-{22,26}.04` Dockerfiles. The flake's `sha256` / `vendorHash` are reset to `pkgs.lib.fakeSha256`; Nix will surface the real hashes on first build, per the existing comment block. * Reverts #19696's Docker pin in `coderd/database/dbtestutil/db.go`. Local `pg_dump` (13+) and the `postgres:13` Docker fallback both work again. * Strips `\restrict` / `\unrestrict` lines in `normalizeDump` so `scripts/migrate-test`'s schema comparison is stable across `pg_dump` versions (the token in those lines is randomized per run). `TestNormalizeDumpStripsRestrict` locks the behavior in. * Regenerates with v1.31.1, picking up the version stamp and one upstream correctness fix in `DeleteLicense` ([sqlc-dev/sqlc#4383](https://github.com/sqlc-dev/sqlc/pull/4383): don't shadow the input parameter when scanning a single-column return). |
||
|
|
eedde58b55 |
chore: bump protobufjs from 7.5.5 to 7.5.6 in /site (#25222)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 7.5.5 to 7.5.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/protobufjs/protobuf.js/releases">protobufjs's releases</a>.</em></p> <blockquote> <h2>protobufjs: v7.5.6</h2> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">7.5.6</a> (2026-04-27)</h2> <h3>Bug Fixes</h3> <ul> <li>Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454">75392ea</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/protobufjs/protobuf.js/blob/protobufjs-v7.5.6/CHANGELOG.md">protobufjs's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">7.5.6</a> (2026-04-27)</h2> <h3>Bug Fixes</h3> <ul> <li>Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454">75392ea</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.3...protobufjs-v7.5.4">7.5.4</a> (2025-08-15)</h2> <h3>Bug Fixes</h3> <ul> <li>invalid syntax in descriptor.proto (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2092">#2092</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/5a3769a465fead089a533ad55c21d069299df760">5a3769a</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.2...protobufjs-v7.5.3">7.5.3</a> (2025-05-28)</h2> <h3>Bug Fixes</h3> <ul> <li>descriptor extensions handling post-editions (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2075">#2075</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/6e255d4ad6982cc857f26e1731c2cedcf5796f68">6e255d4</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.1...protobufjs-v7.5.2">7.5.2</a> (2025-05-14)</h2> <h3>Bug Fixes</h3> <ul> <li>ensure that types are always resolved (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2068">#2068</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/4b51cb2b8450b77f9f5de1c562e7fae93b19d040">4b51cb2</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.0...protobufjs-v7.5.1">7.5.1</a> (2025-05-08)</h2> <h3>Bug Fixes</h3> <ul> <li>optimize regressions from editions implementations (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2066">#2066</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/6406d4c18afae309fc7b5f4a24d9674d85da180b">6406d4c</a>)</li> <li>reserved field inside group blocks fail parsing (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2058">#2058</a>) (<a href="https://github.com/protobufjs/protobuf.js/commit/56782bff0c4b5132806eb1a6bc4d08f930c4aaad">56782bf</a>)</li> </ul> <h2><a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.4.0...protobufjs-v7.5.0">7.5.0</a> (2025-04-15)</h2> <h3>Features</h3> <ul> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/f04ded3a03a3ddd383f0228e2fe2627a51f31aa3">f04ded3</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/ac9a3b9fe3134d48187e41b08d54ffaceddc6c1b">ac9a3b9</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/e5ca5c84e326699e10258367883a54934e0bfe14">e5ca5c8</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/a84409b47f9ba0dba56da1af8054fb54f85d85a1">a84409b</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/9c5a178c4b59e0aa65ecac0bd7420171213b2ff9">9c5a178</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/b2c686721e3b63d092419fa1cbe58e1deb89534e">b2c6867</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/60f3e51087ca2c247473410f39331e1c766aefef">60f3e51</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/a6563617de04d510d6e8865eb6c5067f10247f64">a656361</a>)</li> <li>add Edition 2023 Support (<a href="https://github.com/protobufjs/protobuf.js/commit/869a95b1e5f553c76243aac45619061407a41084">869a95b</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/protobufjs/protobuf.js/commit/2189e5beeca6a70e4c104dfdb9fb8200bc5f81fe"><code>2189e5b</code></a> chore: release protobufjs-v7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2174">#2174</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/75392ea1b78bdc4faba027b5db44ad7c50e9c454"><code>75392ea</code></a> fix: Backport input hardening and CLI fixes to 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2173">#2173</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/8af8d7c0e9800879625f7d0d4a7fb51beb4410cd"><code>8af8d7c</code></a> chore(ci): Fix 7.x release please configuration (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2169">#2169</a>)</li> <li><a href="https://github.com/protobufjs/protobuf.js/commit/e92ca42244ad67203b48d836290062dae037ead6"><code>e92ca42</code></a> chore(ci): Enable release-please for 7.x (<a href="https://redirect.github.com/protobufjs/protobuf.js/issues/2166">#2166</a>)</li> <li>See full diff in <a href="https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.5...protobufjs-v7.5.6">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for protobufjs since your current version.</p> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/coder/coder/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
f355e010e8 |
fix(coderd/database): clean up org memberships when user is soft-deleted (#25149)
The soft-delete cleanup trigger (`delete_deleted_user_resources`)
removed `api_keys`, `user_links`, and `user_secrets` but left
`organization_members` rows intact. When a new user was created with a
previously-deleted user's email, both user IDs had org membership rows
in the same organization, producing duplicate-email members.
Extend the trigger to also delete `organization_members` for the
soft-deleted user. This cascades through the existing
`trigger_delete_group_members_on_org_member_delete`, which cleans up
group memberships automatically. The migration backfills by removing
zombie rows for already-deleted users.
Fixes ENG-831
> [!NOTE]
> 🤖 Generated by Coder Agents
<details>
<summary>Implementation notes</summary>
**Root cause**: `GetOrganizationIDsByMemberIDs` does not join on
`users.deleted = false`, so stale org membership rows for soft-deleted
users were visible to internal queries. Even the filtered queries
(`OrganizationMembers`, `PaginatedOrganizationMembers`) could surface
duplicate emails when a new active user reused a deleted user's email.
**What changed**:
- Migration 000491 extends `delete_deleted_user_resources()` to `DELETE
FROM organization_members WHERE user_id = OLD.id`
- Backfill removes existing zombie org memberships for soft-deleted
users
- `TestOrgMembersSoftDeleteTrigger` covers org membership removal, raw
row cleanup, and cascading group membership cleanup
</details>
|
||
|
|
9810d299d2 |
chore: make dynamic parameters TemplateEmbedPage the default (#25069)
|
||
|
|
36d52ba504 |
feat(.github/workflows): trigger Algolia, ISR, and Vercel deploy on docs/** changes (#25049)
Folds the Algolia/ISR sync trigger and surgical-reindex path computation
into the existing `deploy-docs.yaml` workflow so a single `docs/**` push
fires every update path the docs site needs.
One preflight job feeds two parallel sibling jobs:
- **`changes`** (preflight): diffs `github.event.before` against
`github.sha` to compute `manifest_changed` and `paths_json` (a JSON
array of `{path, status}` objects derived from `git diff --name-status
-z`, capped at 50 entries). The mapping is `A → added`, `M/T →
modified`, `D → deleted`, `R<n> → renamed` (indexed by the new path).
Falls back to whole-branch (emits `paths_json: "[]"`) on
`workflow_dispatch`, the first push to a new branch, fetch failure,
manifest changes (route restructuring would orphan records), or >50
markdown files.
- **`algolia-and-isr`** (always, parallel with `vercel-rebuild`):
HMAC-signed POST to `coder.com/api/algolia-docs-sync` with the
`paths_json` array as part of the body. Refreshes the Algolia `docs`
slice for the `(corpus, ref)` pair and ISR-revalidates every navigable
route the handler touched. Markdown-only edits surface in seconds with
no full rebuild. The step summary line `Mode: \`surgical\` (N path(s))`
lets operators verify which path ran without scrolling through the curl
output.
- **`vercel-rebuild`** (parallel with `algolia-and-isr`, only when
`docs/manifest.json` changed): fires the existing Vercel deploy hook for
a full build. Manifest changes can register or remove routes that
Next.js's `getStaticPaths` only re-evaluates on a full build, so
ISR-per-existing-path is not enough.
Trigger expanded from "main + manifest.json" to "main and `release/*` +
any `docs/**`" so release-branch docs edits also flow through the same
pipeline. The Vercel rebuild path stays gated on manifest changes
regardless of branch.
The pure shell + curl + openssl + jq + awk pipeline is preserved
verbatim. Zero Algolia or Node dependencies in CI.
## Why one workflow instead of two
The original split (a standalone Algolia workflow + the existing
`deploy-docs.yaml`) would have run twice per manifest push, with two
parallel concurrency groups, two GitHub Actions step summaries, and two
ways to forget to add a secret. Folding into one file makes the trigger
story symmetrical: "docs change → all docs surfaces refresh," with the
rebuild path being a strict superset of the ISR path, and the surgical
path strictly cheaper than whole-branch when computable.
## Pre-merge testing
The companion handler PR (coder/coder.com#741) supports an
`ALGOLIA_DOCS_INDEX` env-var override, scoped to `docs_smoke` on the
Vercel preview deploy, so this workflow can be exercised end-to-end
against a disposable index without touching production records. The
smoke harness at `~/audit/smoke/run.sh` (workspace-only) signs and posts
the same body shape this workflow does, so it covers the same crypto
path. To exercise the workflow itself, push a docs-only commit to a
throwaway branch and watch the step summary; the `algolia-and-isr` job
will print the resolved mode.
## Prerequisites before this can do anything useful
1. `secrets.ALGOLIA_DOCS_SYNC_SECRET` must be added as an Actions secret
on this repo. The same value goes on `coder.com`'s Vercel env. The
workflow logs a clear error and aborts with no network call if the
secret is missing.
2. The handler at coder/coder.com#741 must be merged and deployed.
Without it, the POST will 404.
3. `secrets.DEPLOY_DOCS_VERCEL_WEBHOOK` is already in place from the
existing `deploy-docs.yaml`; this PR does not change its usage.
## Demo, validation, and design
- Front-end-only fixes (modal layout, scroll-shadow, rank-order
preservation): coder/coder.com#749 ships these against production today,
independent of this PR.
- Companion handler PR on `coder.com`: coder/coder.com#741. Includes the
surgical-mode plumbing this workflow's `paths_json` output drives.
- Full design lives in the workspace at
`~/plans/algolia-search-revamp.md`. Key sections:
- §6.0–6.2: why the indexer lives in `coder.com`, not here.
- §6.7: per-version add/remove mechanics.
- §6.8: ISR revalidate rationale and same-time refresh.
- §6.9: surgical per-page reindex (workflow + handler + planning rules).
---
This PR was generated by Coder Agents.
|
||
|
|
5e44c71305 |
docs: call out coder/skills setup skill on install and quickstart pages (#25194)
<!-- If you have used AI to produce some or all of this PR, please ensure you have read our [AI Contribution guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING) before submitting. --> |
||
|
|
4b54925abc |
chore: bump the x group across 1 directory with 7 updates (#25198)
Bumps the x group with 4 updates in the / directory: [golang.org/x/crypto](https://github.com/golang/crypto), [golang.org/x/mod](https://github.com/golang/mod), [golang.org/x/net](https://github.com/golang/net) and [golang.org/x/tools](https://github.com/golang/tools). Updates `golang.org/x/crypto` from 0.50.0 to 0.51.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/crypto/commit/b8a14a8d65f88c0c79c139171f1354c69a6cdb8a"><code>b8a14a8</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/crypto/commit/9d9d5078968ddb8a279092c665a24e7de4178778"><code>9d9d507</code></a> x509roots/fallback/bundle: fix bundle test with Go 1.27+</li> <li><a href="https://github.com/golang/crypto/commit/fd0b90d21f9ab4b5dd398e9526b570bfea86e370"><code>fd0b90d</code></a> acme: include Problem in OrderError.Error</li> <li><a href="https://github.com/golang/crypto/commit/b9e53593a6073e6a786c49e9ad27956a9b77e54e"><code>b9e5359</code></a> pbkdf2: turn into a wrapper for crypto/pbkdf2</li> <li><a href="https://github.com/golang/crypto/commit/cc0e4fc1d49127130b0d00612a2eeed2ab745d40"><code>cc0e4fc</code></a> hkdf: forward Extract to the standard library</li> <li><a href="https://github.com/golang/crypto/commit/a8e9237a216b050e1b11e041863825104a6811db"><code>a8e9237</code></a> x509roots/fallback: update bundle</li> <li>See full diff in <a href="https://github.com/golang/crypto/compare/v0.50.0...v0.51.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/mod` from 0.35.0 to 0.36.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/mod/commit/643da9ba74f1165d8cae1505d453b3de3cf21b7b"><code>643da9b</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/mod/commit/ccc3cdf529d1eee2a832437eb1b85240044d21cb"><code>ccc3cdf</code></a> zip: include 'but content has correct sum' note in TestVCS</li> <li><a href="https://github.com/golang/mod/commit/ab3031803214705d2c9f1102318b083e7086a155"><code>ab30318</code></a> zip: update zip hashes for new flate compression</li> <li>See full diff in <a href="https://github.com/golang/mod/compare/v0.35.0...v0.36.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/net` from 0.53.0 to 0.54.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/net/commit/b138e06246cb323f2f380c2b7f7dd91f581dd56b"><code>b138e06</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/net/commit/689f70a42abd350f3a1aaa70b0d13eb9543d927a"><code>689f70a</code></a> quic: fix wrong final size being used for RESET_STREAM frame</li> <li><a href="https://github.com/golang/net/commit/208f306b2f0fd008b388bee2c2644be279778e94"><code>208f306</code></a> http3: increase handshake timeout</li> <li><a href="https://github.com/golang/net/commit/49810da71b9026da9e0d028a6ad8c7730c52d9c4"><code>49810da</code></a> http2: enable net/http wrapping when go >= 1.27</li> <li><a href="https://github.com/golang/net/commit/5e11a5ab891c117eda83b4304d60dd13286c1c76"><code>5e11a5a</code></a> quic: fix data race in streamForFrame</li> <li><a href="https://github.com/golang/net/commit/8c63081cd380ea768db5651941614b73472160ff"><code>8c63081</code></a> http2: use empty Transport rather than DefaultTransport in http2wrap</li> <li><a href="https://github.com/golang/net/commit/fc7b466ca49cb204039630533ece4fc557eb35cd"><code>fc7b466</code></a> http2: add http2wrap test</li> <li><a href="https://github.com/golang/net/commit/15c2cb1875fd727313dc4de909b3ee149422fbe2"><code>15c2cb1</code></a> http2: avoid overflowing 32-bit int when http2wrap enabled</li> <li><a href="https://github.com/golang/net/commit/64651885c2f2d745d77af2d7af2edbf568c179af"><code>6465188</code></a> http2: add wrapped Server</li> <li><a href="https://github.com/golang/net/commit/72f419a894cb0597dd5b6bcf119086bf2af41231"><code>72f419a</code></a> http2: add wrapped ClientConn</li> <li>Additional commits viewable in <a href="https://github.com/golang/net/compare/v0.53.0...v0.54.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/sys` from 0.43.0 to 0.44.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/sys/commit/fb1facd76f95fa87c151018200ea5e4892ff115d"><code>fb1facd</code></a> windows: avoid uint16 overflow in NewNTUnicodeString</li> <li><a href="https://github.com/golang/sys/commit/94ad893e1e59c1d079221324d38945d2aad8703f"><code>94ad893</code></a> windows: add GetIfTable2Ex, GetIpInterface{Entry,Table}, GetUnicastIpAddressT...</li> <li><a href="https://github.com/golang/sys/commit/54fe89f8411576c06b345b341ca79a77d878a4ad"><code>54fe89f</code></a> cpu: use IsProcessorFeaturePresent to calculate ARM64 on windows</li> <li><a href="https://github.com/golang/sys/commit/df7d5d7b60641d17d87e2b50911124cb65f954fd"><code>df7d5d7</code></a> unix: automatically remove container created by mkall.sh</li> <li><a href="https://github.com/golang/sys/commit/68a4a8e945b22751c1a619261b1d755372a1d5f7"><code>68a4a8e</code></a> unix: avoid nil pointer dereference in Utime</li> <li><a href="https://github.com/golang/sys/commit/690c91f6ecf3b3ef141ad2aedb1306a868b3a176"><code>690c91f</code></a> unix: add CPUSetDynamic for systems with more than 1024 CPUs</li> <li>See full diff in <a href="https://github.com/golang/sys/compare/v0.43.0...v0.44.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/term` from 0.42.0 to 0.43.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/term/commit/3c3e4855f7d2eb06c3e48933554add9ec6b599b5"><code>3c3e485</code></a> go.mod: update golang.org/x dependencies</li> <li>See full diff in <a href="https://github.com/golang/term/compare/v0.42.0...v0.43.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/text` from 0.36.0 to 0.37.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/text/commit/3ef517e623a4bfc08d6457f87d73afda7af7d8e1"><code>3ef517e</code></a> go.mod: update golang.org/x dependencies</li> <li>See full diff in <a href="https://github.com/golang/text/compare/v0.36.0...v0.37.0">compare view</a></li> </ul> </details> <br /> Updates `golang.org/x/tools` from 0.44.0 to 0.45.0 <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/tools/commit/2aabba0e4be44cc8f254ced118a7156d04bbc9f3"><code>2aabba0</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/tools/commit/ef989b3f45baff2849e87f4a70d9a189be5a6959"><code>ef989b3</code></a> go/types/internal/play: show Info.Instances[Ident]</li> <li><a href="https://github.com/golang/tools/commit/21d44f2f2bb3f3a8e06e35523d14bb70cb275c89"><code>21d44f2</code></a> go/analysis/passes/inline: document skipping of TestF->F calls</li> <li><a href="https://github.com/golang/tools/commit/ec83c2190d81a18bbd472cc1498575b168017e5d"><code>ec83c21</code></a> go/analysis/passes/modernize: minmax: only remove exact userdefined</li> <li><a href="https://github.com/golang/tools/commit/5625353d39195f1deb9261c5ee983abbdc4a15ca"><code>5625353</code></a> go/analysis/passes/modernize: improve value variable name generation</li> <li><a href="https://github.com/golang/tools/commit/15a3bd5d4ce0651f5cf43ea125db2110c67b257b"><code>15a3bd5</code></a> gopls/internal/analysis/errorsastype: imporove example clarity</li> <li><a href="https://github.com/golang/tools/commit/cd57ef8f8dd7a30ef500bfe1eef0779223cbdfc3"><code>cd57ef8</code></a> go/packages: include dependency errors when CompiledGoFiles is missing</li> <li><a href="https://github.com/golang/tools/commit/053fdbcef55e8f977d8decc0fde2920c61eb5374"><code>053fdbc</code></a> go/analysis/passes/modernize: minmax: fix pure operands only</li> <li><a href="https://github.com/golang/tools/commit/bf84681c4a0185014c089cffd533e22bbeffcb49"><code>bf84681</code></a> go/analysis/passes/errorsas: add example of invalid errors.As use</li> <li><a href="https://github.com/golang/tools/commit/23921d1decfe5da40309ac183353c8cb38b03dfa"><code>23921d1</code></a> gopls: add errorsastype analyzer</li> <li>Additional commits viewable in <a href="https://github.com/golang/tools/compare/v0.44.0...v0.45.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
0234422a55 |
chore: bump google.golang.org/api from 0.277.0 to 0.278.0 (#25201)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.277.0 to 0.278.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.278.0</h2> <h2><a href="https://github.com/googleapis/google-api-go-client/compare/v0.277.0...v0.278.0">0.278.0</a> (2026-05-05)</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/3582">#3582</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/76b1187e506ac0f48caac67907dd0805b253f74c">76b1187</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3584">#3584</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/e36c88361d11545583325c3ac6bdbd9cf1f1a7d0">e36c883</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.277.0...v0.278.0">0.278.0</a> (2026-05-05)</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/3582">#3582</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/76b1187e506ac0f48caac67907dd0805b253f74c">76b1187</a>)</li> <li><strong>all:</strong> Auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3584">#3584</a>) (<a href="https://github.com/googleapis/google-api-go-client/commit/e36c88361d11545583325c3ac6bdbd9cf1f1a7d0">e36c883</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/googleapis/google-api-go-client/commit/07c758daacbc24e32753c3f1b537c7f6cce626f0"><code>07c758d</code></a> chore(main): release 0.278.0 (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3583">#3583</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/e36c88361d11545583325c3ac6bdbd9cf1f1a7d0"><code>e36c883</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3584">#3584</a>)</li> <li><a href="https://github.com/googleapis/google-api-go-client/commit/76b1187e506ac0f48caac67907dd0805b253f74c"><code>76b1187</code></a> feat(all): auto-regenerate discovery clients (<a href="https://redirect.github.com/googleapis/google-api-go-client/issues/3582">#3582</a>)</li> <li>See full diff in <a href="https://github.com/googleapis/google-api-go-client/compare/v0.277.0...v0.278.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> |
||
|
|
969da320ec |
feat: export Coder Agents debug logs (#25039)
Adds JSON export actions to the Coder Agents Debug panel so users can download either the current chat's recent debug runs or one expanded run for support sharing. The export reuses the existing chat debug endpoints and react-query cache, adds Storybook and unit coverage for the JSON envelope, and updates the chat debug logging docs with UI and cURL instructions. Refs CODAGT-280. Generated by Coder Agents. <details> <summary>Implementation notes</summary> - Chat-level export fetches full detail for each listed debug run with `queryClient.fetchQuery(chatDebugRun(chatId, run.id))` and writes a single JSON file. - Run-level export uses the already-loaded detail query data from an expanded run card. - The JSON envelope includes `version`, `scope`, `exported_at`, `chat_id`, and either `runs` or `run`. - The chat-level export reflects the current backend list endpoint behavior, up to the 100 newest debug runs. - Agent-browser dogfooding verified files were downloaded and that `jq` validated the chat-level and run-level JSON contents. </details> |
||
|
|
147f50c5e8 |
fix(agent/x/agentmcp): watch MCP config files for late-appearing or rewritten config (#25172)
## Bug `agent/x/agentmcp/Manager` resolves its config paths once at boot, calls `Reload`, and then only re-stats them lazily when a `GET /api/v0/mcp/tools` request arrives (PR #24700). If any of the manager's MCP config files (`~/.mcp.json` by default, or whatever paths `agentcontextconfig.MCPConfigFiles()` resolves from `CODER_AGENT_EXP_MCP_CONFIG_FILES`) is created, atomically rewritten, or removed _after_ that initial `Reload` and _before_ the next tools HTTP request, the manager keeps serving the stale (often empty) snapshot. `parseAndDedup` silently swallows `fs.ErrNotExist`, so a late-appearing file looks indistinguishable from "no config" until something pokes the manager again. This affects any workspace where the file lands after `MarkStartupSettled` fires, including: - a startup script that writes `~/.mcp.json` after MCP init - a user creating or editing the file mid-session - an installer, dotfiles step, or sync tool writing the file later in startup - another agent process (Claude Code, etc.) producing the file out-of-band - editor rewrites that land as `Write + Chmod + Rename` bursts ### Concrete repro (dual-agent workspace) The race is easiest to reproduce on dual-agent workspaces (inner sandbox + outer host), where the inner agent's `scriptRunner` has `script_count=0` and `mcpManager.Reload` fires at ~t+0.3 s while the host agent writes `~/.mcp.json` ~21 s later. Timeline from `workspace-otto-aa16`: - agent up `20:23:38.918` - lifecycle Ready `20:23:39.200` - MCP config file Birth `20:24:00.460` (~21 s gap) - no MCP log lines for 8 minutes - first `GET /api/v0/mcp/tools` at `20:32:11.812` logs `[warn] mcp: mcp reload canceled by caller`, takes 4946 ms; subsequent turns are cached at 2 ms. The single-agent case has the same race; it's just usually narrow enough that the next HTTP request masks it, at the cost of a multi-second stall on the first call that has to do the lazy reload itself. PR #25034's `MarkStartupSettled` does not help: "settled" fires before the file is necessarily on disk. ## Fix Add an fsnotify-backed `configWatcher` to `agent/x/agentmcp/Manager`. The watcher consumes whatever paths the manager is told to reload, which is the same `[]string` returned by `agentcontextconfig.MCPConfigFiles()`. For each path the watcher: - Watches the **parent directory** of the path, not the file itself. This handles late creation, atomic rewrite (rename + create), and deletion uniformly because inotify watches on individual non-existent files return `ENOENT` and are lost across renames. The pattern matches `agent/agentcontainers/watcher`. - Walks up to the first existing **ancestor directory** when the parent does not yet exist, and re-arms deeper on `Create` events that promote an unrealized path. - Refcounts directory watches so multiple configured paths sharing a parent dir only register one inotify watch. - Resolves symlinks **once at arming time** via `filepath.EvalSymlinks`; never chases arbitrary symlink targets on events. - Debounces multi-event editor writes through a single `quartz.AfterFunc` timer so a `Write + Chmod + Rename` burst produces one reload. - Fires a debounced callback that calls `Manager.Reload`, which routes through the existing singleflight so concurrent triggers coalesce. - Re-syncs on every `Reload` call so a future path-list change is picked up. Lifecycle: the watcher is armed lazily on the first `Reload` (no goroutine cost for unit tests that never reload). `Manager.Close` marks the manager closed and closes its `closedCh` before tearing down the watcher, so any in-flight watcher-driven reload observes the close via `waitReload` and returns `ErrManagerClosed` instead of blocking `firesWG.Wait()` on a stuck connect. The watcher then waits for its goroutine and any in-flight debounced `fire` callback before returning. `parseAndDedup` behavior is unchanged: `fs.ErrNotExist` still records an empty snapshot. With the watcher armed before that snapshot is committed, any `Create` event that races `parseAndDedup` is still delivered. This is the agent-side complement to PR #25169, which fixes chatd's mid-turn workspace MCP discovery. `MarkStartupSettled` semantics are not changed. ## Tests (`agent/x/agentmcp/configwatcher_internal_test.go`) All new tests pass with the fix and fail without it. No `time.Sleep`; synchronization uses `testutil.Eventually` for fsnotify-driven assertions and the quartz mock clock for debounce assertions. - `TestWatcher_LateFileTriggersReload` - the late-file regression: empty dir, settle startup, `Reload` sees no file, write the file later, watcher reloads, tools appear. - `TestWatcher_RewriteTriggersReload` - existing file overwritten with a new server list, watcher reloads, cache reflects new server. - `TestWatcher_RemovalTransitionsToEmpty` - delete the file, watcher reloads, manager transitions to empty cleanly. - `TestWatcher_DebouncesBurst` - quartz mock clock; three back-to-back `scheduleFire` calls produce exactly one `onChange` after `AdvanceNext`. - `TestWatcher_CloseStopsGoroutine` - construct/Reload/Close five times to surface goroutine or fd leaks under `-race`. - `TestWatcher_DualAgentHTTPNoStall` - integration: write file after `Reload`, wait for watcher reload, then `GET /tools` returns the MCP tools in less than `testutil.WaitShort` instead of the multi-second "reload canceled" stall. - `TestWatcher_LateParentDirTriggersReload` - parent dir doesn't exist at `Reload` time; create the dir then the file; watcher re-arms deeper and reloads. - `TestWatcher_SharedParentRefcount` - two configured paths share a parent dir; only one inotify watch is registered and both reload on changes. - `TestWatcher_CloseDoesNotStallOnInFlightReload` - installs a `connectStartedHook` to block a watcher-driven reload mid-`connectAll`, then asserts `Close()` returns within `WaitMedium`. Regression-verified: reverting the close-ordering causes the test to time out. ## Acceptance checklist - [x] `go test ./agent/x/agentmcp/... -race -count=1` passes (also `-count=5`). - [x] All `./agent/...` tests pass under `-race -short`. - [x] No emdash, endash, or ` -- `; `scripts/check_emdash.sh` clean. - [x] No `time.Sleep` in tests. - [x] New tests fail without the fix and pass with it (verified by temporarily disabling `m.armWatcher(paths)` and by reverting `Close()` ordering). ## Out of scope No changes to chatd's mid-turn workspace MCP discovery (PR #25169) or `MarkStartupSettled` semantics. --- <sub>This pull request was prepared by a [Coder Agents](https://coder.com/docs/admin/ai-coder) run.</sub> |