Surfaces a chat's pinned workspace-context resources on the single-chat
GET and refresh responses, so clients can show *what* context the prompt
was built from, not just whether it drifted.
## What's included
- **codersdk**: `ChatContextResource` (plus `ChatContextResourceKind`
and `ChatContextResourceStatus`) and `ChatContextMCPTool`, and a new
`Chat.Context.Resources` field (metadata only, no bodies). It is
populated only on the single-chat GET/refresh response; list and watch
payloads stay nil to remain lightweight.
- **coderd/x/chatd**: `Server.ContextResources`, which builds the
metadata-only list from the chat's pinned `chat_context_resources` rows.
Non-OK resources (invalid / unreadable / oversize / excluded) are
reported with their status and error so the UI can explain why a
resource was dropped from the prompt instead of silently omitting it.
The shared protojson body decoders are extracted so the prompt and
detail paths reuse them.
- **coderd**: `getChat` and `refreshChatContext` enrich the response
with the resource list. Failures are non-fatal (the chat stays usable
without the detail).
## Scope / what's deferred
This is an incremental split from #26466. This PR reports only the
**resource inventory**. The pinned-context drift *diff* (the per-source
`changes` set and the "View changes" dialog) is intentionally deferred
to a later split; the existing `dirty` bit already signals that context
changed. MCP resources are reported for display only; they are not
injected into the prompt (a future RFC item).
<details>
<summary>Design notes</summary>
- The resource list is the chat's full pinned inventory (instruction
files, skills, and MCP configs/servers), preserving the query's `source
ASC` order. OK-but-empty instruction files, OK skills with no name, and
untracked kinds (reserved plugin/hook/subagent/command) are skipped.
- MCP tool names are reported with the agent's `"<server>__"` prefix
stripped so they read as the server exposes them.
- The detail is computed on read and attached only on the single-chat
GET and refresh responses; list and watch payloads omit it to stay
lightweight.
- `refreshChatContext` enriches its own response (mirroring `getChat`)
so the client reflects a refresh immediately, without a full reload.
</details>
<details>
<summary>Testing</summary>
- `go test ./coderd/x/chatd/ -run
'TestPinnedContextResources|TestContextResources|TestChatContextDirtyFromAgentPush'`
(unit + integration on embedded Postgres) passes. The integration test
exercises the GET and refresh enrichment end-to-end.
- `go build`, `go vet`, `golangci-lint`, and `gofmt` are clean.
- `make gen` regenerated `apidoc`, `swagger.json`,
`docs/reference/api/*`, and `typesGenerated.ts`.
</details>
---
*This PR was created by Coder Agents on behalf of @kylecarbs.*