diff --git a/Makefile b/Makefile index e45005856d..e9683190d8 100644 --- a/Makefile +++ b/Makefile @@ -736,7 +736,7 @@ endif # GitHub Actions linters are run in a separate CI job (lint-actions) that only # triggers when workflow files change, so we skip them here when CI=true. LINT_ACTIONS_TARGETS := $(if $(CI),,lint/actions/actionlint) -lint: lint/shellcheck lint/go lint/ts lint/examples lint/helm lint/site-icons lint/markdown lint/check-scopes lint/migrations lint/bootstrap lint/architecture lint/emdash lint/agents lint/mise-versions $(LINT_ACTIONS_TARGETS) +lint: lint/shellcheck lint/go lint/ts lint/examples lint/helm lint/site-icons lint/markdown lint/docs-html lint/check-scopes lint/migrations lint/bootstrap lint/architecture lint/emdash lint/agents lint/mise-versions $(LINT_ACTIONS_TARGETS) .PHONY: lint # Fast lint subset for lightweight hooks. Some targets use mise-managed tools. @@ -780,6 +780,15 @@ lint/emdash: bash scripts/check_emdash.sh .PHONY: lint/emdash +# Fails when docs Markdown contains invalid inline HTML the docs site drops or +# mangles: swallowed angle-bracket placeholders (e.g. ), void-element +# end tags (
), capitalized or unregistered component tags (e.g. ), +# and unclosed container tags. +lint/docs-html: + echo "--- check for invalid inline HTML in docs" + go run ./scripts/docshtmlcheck +.PHONY: lint/docs-html + lint/architecture: ./scripts/check_architecture.sh .PHONY: lint/architecture diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 8abc40867e..61b2ab3263 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -168,7 +168,7 @@ AI GATEWAY OPTIONS: this option seeds provider configuration at startup only exactly once. It will not be used in service runtime. The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form - of 'https://bedrock-runtime..amazonaws.com'. + of `https://bedrock-runtime..amazonaws.com`. --ai-gateway-bedrock-small-fastmodel string, $CODER_AI_GATEWAY_BEDROCK_SMALL_FAST_MODEL (default: global.anthropic.claude-haiku-4-5-20251001-v1:0) Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 18d3a89cdc..444a32d74d 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -839,7 +839,7 @@ aibridge: bedrock_base_url: "" # Deprecated: use --ai-gateway-bedrock-region or CODER_AI_GATEWAY_BEDROCK_REGION # instead. The AWS Bedrock API region to use. Constructs a base URL to use for the - # AWS Bedrock API in the form of 'https://bedrock-runtime..amazonaws.com'. + # AWS Bedrock API in the form of `https://bedrock-runtime..amazonaws.com`. # (default: , type: string) bedrock_region: "" # Deprecated: use --ai-gateway-bedrock-model or CODER_AI_GATEWAY_BEDROCK_MODEL @@ -943,7 +943,7 @@ ai_gateway: # option seeds provider configuration at startup only exactly once. It will not be # used in service runtime. The AWS Bedrock API region to use. Constructs a base # URL to use for the AWS Bedrock API in the form of - # 'https://bedrock-runtime..amazonaws.com'. + # `https://bedrock-runtime..amazonaws.com`. # (default: , type: string) bedrock_region: "" # Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, this diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 9f7da2078c..1845469f2c 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -17528,7 +17528,7 @@ const docTemplate = `{ "type": "string" }, "name": { - "description": "Name is the tool name with the \"\u003cserver\u003e__\" prefix the agent adds\nstripped, so it reads as the server exposes it.", + "description": "Name is the tool name with the ` + "`" + `\u003cserver\u003e__` + "`" + ` prefix the agent adds\nstripped, so it reads as the server exposes it.", "type": "string" } } diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index f3bfe8591d..6a4a259997 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -15754,7 +15754,7 @@ "type": "string" }, "name": { - "description": "Name is the tool name with the \"\u003cserver\u003e__\" prefix the agent adds\nstripped, so it reads as the server exposes it.", + "description": "Name is the tool name with the `\u003cserver\u003e__` prefix the agent adds\nstripped, so it reads as the server exposes it.", "type": "string" } } diff --git a/codersdk/chats.go b/codersdk/chats.go index 2cfbf3048b..f6f2e1540c 100644 --- a/codersdk/chats.go +++ b/codersdk/chats.go @@ -224,7 +224,7 @@ const ( // ChatContextTool is one tool exposed by a pinned MCP server, reported on the // single-chat GET response. Metadata only; the input schema is omitted. type ChatContextTool struct { - // Name is the tool name with the "__" prefix the agent adds + // Name is the tool name with the `__` prefix the agent adds // stripped, so it reads as the server exposes it. Name string `json:"name"` // Description is the tool's human-readable summary; may be empty. diff --git a/codersdk/deployment.go b/codersdk/deployment.go index dd756a036e..bb108c79b4 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -1954,7 +1954,7 @@ communicating directly.`, } aiGatewayBedrockRegion := serpent.Option{ Name: "AI Gateway Bedrock Region", - Description: aiGatewayProviderSeedingDeprecated + "The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of 'https://bedrock-runtime..amazonaws.com'.", + Description: aiGatewayProviderSeedingDeprecated + "The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of `https://bedrock-runtime..amazonaws.com`.", Flag: "ai-gateway-bedrock-region", Env: "CODER_AI_GATEWAY_BEDROCK_REGION", Value: &c.AI.BridgeConfig.LegacyBedrock.Region, @@ -4471,7 +4471,7 @@ Write out the current server config as YAML to stdout.`, { Name: "AI Bridge Bedrock Region", Description: "Deprecated: use --ai-gateway-bedrock-region or CODER_AI_GATEWAY_BEDROCK_REGION instead. The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of " + - "'https://bedrock-runtime..amazonaws.com'.", + "`https://bedrock-runtime..amazonaws.com`.", Flag: "aibridge-bedrock-region", Env: "CODER_AIBRIDGE_BEDROCK_REGION", Value: &c.AI.BridgeConfig.LegacyBedrock.Region, diff --git a/docs/reference/api/chats.md b/docs/reference/api/chats.md index f84bf3d49a..8cd963f356 100644 --- a/docs/reference/api/chats.md +++ b/docs/reference/api/chats.md @@ -165,7 +165,7 @@ Status Code **200** | `»»» status` | [codersdk.ChatContextResourceStatus](schemas.md#codersdkchatcontextresourcestatus) | false | | Status is the resource's health. Non-ok resources (invalid, unreadable, oversize, excluded) are still reported so the UI can surface why a resource was dropped from the prompt instead of silently omitting it; their body-specific fields (skill name, tools) are empty. | | `»»» tools` | array | false | | Tools lists the tools exposed by an MCP server. Populated only for the mcp_server kind; nil otherwise. | | `»»»» description` | string | false | | Description is the tool's human-readable summary; may be empty. | -| `»»»» name` | string | false | | Name is the tool name with the "__" prefix the agent adds stripped, so it reads as the server exposes it. | +| `»»»» name` | string | false | | Name is the tool name with the `__` prefix the agent adds stripped, so it reads as the server exposes it. | | `» created_at` | string(date-time) | false | | | | `» diff_status` | [codersdk.ChatDiffStatus](schemas.md#codersdkchatdiffstatus) | false | | | | `»» additions` | integer | false | | | diff --git a/docs/reference/api/schemas.md b/docs/reference/api/schemas.md index db722b7cc9..95202510ff 100644 --- a/docs/reference/api/schemas.md +++ b/docs/reference/api/schemas.md @@ -2596,7 +2596,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | Name | Type | Required | Restrictions | Description | |---------------|--------|----------|--------------|-------------------------------------------------------------------------------------------------------------------| | `description` | string | false | | Description is the tool's human-readable summary; may be empty. | -| `name` | string | false | | Name is the tool name with the "__" prefix the agent adds stripped, so it reads as the server exposes it. | +| `name` | string | false | | Name is the tool name with the `__` prefix the agent adds stripped, so it reads as the server exposes it. | ## codersdk.ChatCost diff --git a/docs/reference/cli/server.md b/docs/reference/cli/server.md index f4ae058d87..1ddd15dbdc 100644 --- a/docs/reference/cli/server.md +++ b/docs/reference/cli/server.md @@ -1814,7 +1814,7 @@ Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, this opti | Environment | $CODER_AI_GATEWAY_BEDROCK_REGION | | YAML | ai_gateway.bedrock_region | -Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, this option seeds provider configuration at startup only exactly once. It will not be used in service runtime. The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of 'https://bedrock-runtime..amazonaws.com'. +Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, this option seeds provider configuration at startup only exactly once. It will not be used in service runtime. The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form of `https://bedrock-runtime..amazonaws.com`. ### --ai-gateway-bedrock-access-key diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 369b2fe72c..263d399ea1 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -169,7 +169,7 @@ AI GATEWAY OPTIONS: this option seeds provider configuration at startup only exactly once. It will not be used in service runtime. The AWS Bedrock API region to use. Constructs a base URL to use for the AWS Bedrock API in the form - of 'https://bedrock-runtime..amazonaws.com'. + of `https://bedrock-runtime..amazonaws.com`. --ai-gateway-bedrock-small-fastmodel string, $CODER_AI_GATEWAY_BEDROCK_SMALL_FAST_MODEL (default: global.anthropic.claude-haiku-4-5-20251001-v1:0) Deprecated: manage AI Providers from the Coder UI or HTTP API. If set, diff --git a/scripts/docshtmlcheck/README.md b/scripts/docshtmlcheck/README.md new file mode 100644 index 0000000000..e3a1a48550 --- /dev/null +++ b/scripts/docshtmlcheck/README.md @@ -0,0 +1,72 @@ +# docshtmlcheck + +`docshtmlcheck` fails CI when Markdown under `docs/` contains invalid inline +HTML that the documentation site's renderer silently drops or mangles. It runs +as `make lint/docs-html` (part of `make lint`). + +## What it catches + +- **Swallowed angle-bracket placeholders.** An unwrapped placeholder such as + `` or `__` is parsed as an unknown HTML tag and stripped from + the rendered page, so readers see broken text. Wrap placeholders in backticks + so they render as inline code (see + [`docs/about/contributing/documentation.md`](../../docs/about/contributing/documentation.md#placeholders-in-angle-brackets)). + This also covers CLI `--help` strings and Swagger annotations, whose text is + generated into `docs/reference/**`. +- **Void-element end tags** such as `
`. Void elements like `
`, ``, + and `
` have no end tag. +- **Capitalized or unregistered component tags** such as `` or ``. + The docs renderer reads a capitalized tag as a component reference and drops + it unless the component is registered (only the lowercase `` + directive is). Any name outside the standard HTML5 element set is reported the + same way. +- **Unclosed container tags**, for example a `
` that is never + closed and leaks its wrapper over the rest of the page. + +## How it works + +Each file is parsed with [goldmark](https://github.com/yuin/goldmark) and only +raw-HTML nodes are inspected, so angle brackets inside fenced code blocks, +inline code spans, HTML comments, and `` / `` autolinks +are ignored. Each raw-HTML node is tokenized as a whole with +`golang.org/x/net/html`, so a tag whose attributes wrap across lines is not +torn in half. A tag whose raw name is capitalized is reported as a component +reference; otherwise any name outside the standard HTML5 element set (plus the +intentional `` renderer component, which is still balance-checked) is +reported. Inline SVG and MathML are intentionally **not** in the allowed set (no +docs page uses them); add the element to `allowedElements` in `main.go` if that +changes. A finding on a generated page under `docs/reference/**` also prints a +note pointing at the generator source, since edits to the generated file do not +persist. + +## Limitations + +A few gaps are accepted because no docs page hits them today: + +- A placeholder whose name is itself a real HTML element (``, `