Skip to content

Commit f95f71e

Browse files
Merge pull request #384 from agentgateway/kkb-links-4-13-26
Link fixes and added link fix skill 4/13/26
2 parents a11c78b + 51134f2 commit f95f71e

67 files changed

Lines changed: 276 additions & 91 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
name: fix-broken-links
3+
description: Review a Lychee link checker report from a GitHub issue and propose fixes for errors, warnings (broken anchors), and redirects in a Hugo docs repo. Use when the user asks to "fix broken links", "review the link report", "triage link checker issues", or points at a link checker issue (for example agentgateway/website#383).
4+
version: 1.0.0
5+
---
6+
7+
# Fix broken links skill
8+
9+
Use this skill when the user provides a Lychee link checker report (usually posted as a GitHub issue) and asks to triage or fix the findings in a Hugo-based documentation repository.
10+
11+
The report has three sections: **Errors**, **Warnings (broken anchors)**, and **Redirects**. Each bullet contains the link, followed by `Found on:` with one or more source HTML paths under `public/`.
12+
13+
---
14+
15+
## Input
16+
17+
The user will give you a link to a GitHub issue, or paste the issue body. Example: https://github.com/agentgateway/website/issues/383
18+
19+
If given a URL, fetch the issue body with:
20+
21+
```sh
22+
gh issue view <N> --repo <owner>/<repo> --json body -q .body
23+
```
24+
25+
---
26+
27+
## Mapping source paths to editable files
28+
29+
Source paths in the report look like `public/docs/kubernetes/latest/install/argocd/index.html`. These are built HTML files — you cannot edit them directly. Map them to source files:
30+
31+
1. **Thin content wrapper**: Under `content/` (the Hugo content directory). Often a `.md` file whose body is just `{{< reuse "..." >}}` or a similar include.
32+
2. **Asset / reuse body**: If the content wrapper is a reuse or include, the real prose lives under a shared directory (in this repo, `assets/agw-docs/pages/...`). **Edit the shared file, not the thin wrapper.** Editing the shared file fixes all versions that reuse it.
33+
3. **Snippet**: A smaller shared fragment (in this repo, under `assets/agw-docs/snippets/...`) if referenced through another reuse chain.
34+
35+
How to tell which category a page falls in:
36+
- Read the content file at the mapped path.
37+
- If the body is essentially one `{{< reuse "..." >}}` shortcode (or similar include), follow that reference to the shared file and edit there.
38+
- If the body has real prose, edit the content file directly.
39+
40+
Example mapping:
41+
- `public/docs/kubernetes/latest/install/argocd/index.html`
42+
→ content wrapper: `content/docs/kubernetes/latest/install/argocd.md`
43+
→ if wrapper is `{{< reuse "agw-docs/pages/install/argocd.md" >}}`, edit `assets/agw-docs/pages/install/argocd.md`
44+
45+
---
46+
47+
## Scope — what to skip
48+
49+
- **Reference docs**: Skip any source path under a `reference/` directory (for example `public/docs/kubernetes/*/reference/api/index.html`, `reference/helm/*`, `reference/cel/*`). These are typically generated from external code repos and shouldn't be hand-edited in the docs repo. Report them as "skipped — generated reference content" and move on.
50+
- **Other generated content**: Apply the same rule for any other directory the repo treats as build output of external sources. Check the repo's README or CONTRIBUTING guide if unsure.
51+
52+
### Auto-generated content sources (for future reference)
53+
54+
Reference topics are still skipped during normal triage (see above). But when you do want to chase a broken link upstream — or report which upstream repo a broken reference link traces to — use this map of where each `reference/` output gets generated from. The agentgateway workflow that produces these is [reference-docs.yaml](../../../.github/workflows/reference-docs.yaml).
55+
56+
| Generated output (in this repo) | Upstream source repo | Upstream source path | Generator |
57+
|---|---|---|---|
58+
| `assets/agw-docs/pages/reference/api/api-{version}.md` (API CRD reference) | `agentgateway/agentgateway` | `controller/api/v1alpha1/agentgateway/` | `github.com/elastic/crd-ref-docs` |
59+
| `assets/agw-docs/pages/reference/api/api-{version}.md` (shared types appended, includes CEL) | `agentgateway/agentgateway` | `controller/api/v1alpha1/shared/` | `scripts/generate-shared-types.py` |
60+
| `assets/agw-docs/pages/reference/helm/{version}/agentgateway.md` and `agentgateway-crds.md` | `agentgateway/agentgateway` | `install/helm/agentgateway/` and `install/helm/agentgateway-crds/` | `github.com/norwoodj/helm-docs` via `scripts/generate-ref-docs.py` |
61+
| `assets/agw-docs/snippets/metrics-control-plane-{version}.md` | `agentgateway/agentgateway` | control plane metrics output | `scripts/generate-ref-docs.py` |
62+
63+
When you report a `reference/` link as skipped, include the upstream repo if you can identify it from the table above — that helps the user know whether the underlying fix needs an upstream PR or a regeneration of the docs.
64+
65+
---
66+
67+
## Triage workflow
68+
69+
Work through the report top-down: Errors first, then Warnings, then Redirects. For each entry:
70+
71+
1. Skip if the source is under `reference/` or another generated directory (see above).
72+
2. Identify the source file(s) to edit using the mapping above.
73+
3. Apply the rules for that category below.
74+
4. Record the finding in a summary you'll report to the user at the end.
75+
76+
**Do NOT open a PR or push commits.** Make local edits only. The user will review.
77+
78+
### Errors
79+
80+
Broken links (non-anchor, or anchors where the page itself is gone).
81+
82+
1. **Check for false positives first.** Fetch the URL (WebFetch) to see if it actually loads. If it does, note it as a false positive and suggest a likely reason:
83+
- **JS-rendered anchors** (common for kubernetes.io tabs, AWS console, Azure Learn, Google AI docs, and other modern docs sites). Lychee parses static HTML and looks for `id="..."`. Pages that build anchors with JavaScript at runtime have no matching IDs in the static HTML, so lychee reports them broken even though they work in browsers. There is no lychee config to fix this short of running JS. To verify: curl the page, grep for `id=` near the expected anchor name. If the page's static HTML has *no* IDs that match the expected pattern *and* the page loads in a browser to the right section, it's JS-rendered. **Important**: a missing static `id=` could also mean the anchor is genuinely broken (the section was renamed) — always confirm in a browser before calling it a false positive.
84+
- Lychee user-agent blocked or rate limiting.
85+
- URL-encoding Lychee mishandles (for example trailing `%29` from a stray `)` in markdown).
86+
- Link is inside a tab / collapsible / conditional-render that Lychee parses differently.
87+
2. **Try to find the new location.** Read the source file and look at the text surrounding the link. If the link is clearly meant to point somewhere specific (for example, a markdown link like `[install guide](URL)`), check whether the target content moved. Browse the target site (WebFetch the parent directory listing or use a site search) to locate the current URL.
88+
3. **Apply the fix** in the mapped source file (shared/asset file if the content wrapper is a reuse, otherwise the content file). If you cannot confidently determine the new URL, record it as "needs human review" and do not edit.
89+
90+
### Warnings — broken anchors
91+
92+
The page exists but the `#fragment` does not resolve.
93+
94+
1. Fetch the target page and check the current anchor IDs (search for `id="..."` in the HTML).
95+
2. Map the old anchor to the current one — sections are often renamed (for example `#health-checks``#health-check-policies`).
96+
3. If the anchor's content moved to a different page, update both the path and the fragment.
97+
4. If the content was removed entirely, consider removing the link or changing it to a page-level link. Flag this for review.
98+
5. For warnings on external sites (kubernetes.io, git.k8s.io, gateway-api.sigs.k8s.io, etc.) that look like false positives, verify in-browser — these often work but Lychee's fragment validator can be strict about URL-encoded anchors. Leave a note rather than silently excluding.
99+
100+
### Redirects
101+
102+
Lychee reports each as `original → final`.
103+
104+
1. **Skip auth/login redirects.** If `final` is a sign-in / SSO / login page, the original URL is fine — users will authenticate and reach the right place. Don't edit. Report it back though.
105+
2. **Skip canonical short-form / always-redirecting URLs.** Some URLs are intentionally short forms that always redirect to the current target. Don't update these — instead, suggest adding them to `lychee.toml`'s exclude list so they stop appearing in future reports. Examples:
106+
- `github.com/<owner>/<repo>/releases/latest` → versioned tag (the `/latest` URL is intentional — it auto-tracks the newest release).
107+
- `discord.gg/<code>``discord.com/invite/<code>` (the short form is canonical).
108+
- `github.com/user-attachments/assets/<id>` → time-limited S3 signed URL (the short form is the only stable URL).
109+
3. **Otherwise, update the source** to the `final` URL. Common cases are vendor doc restructures (Microsoft Learn, Google Cloud, Anthropic, AWS) and project rebrands or host moves.
110+
111+
---
112+
113+
## Making edits
114+
115+
- Edit **shared/asset files** when the content wrapper is a reuse or include. This fixes all versions at once.
116+
- Edit **content files** only when the content is version-specific and not a reuse.
117+
- If the same broken link appears in multiple source files that all trace back to the same shared file, edit the shared file once.
118+
- Use the `Edit` tool with enough surrounding context to make the match unique.
119+
- For repeated identical replacements across many files (typical for redirect fixes), batch with `sed -i ''` over a `find` of the relevant directories. Always quote URLs and escape `.` and `/` carefully. After a batch, grep to confirm the old pattern is gone.
120+
- **Watch for trailing-slash variants.** A URL like `https://jwt.io/` appears in the report, but docs often also contain `https://jwt.io` (no slash) in other files. A sed pattern of `jwt\.io/` won't match the no-slash form. Either run two sed passes (with and without the trailing slash), or use a pattern that tolerates both (for example, matching inside markdown link parentheses: `(https://jwt\.io)` and `(https://jwt\.io/)`). After the batch, grep for the base hostname (without slash) to catch any stragglers.
121+
122+
### Conditional content for cross-variant link breakage
123+
124+
If a link works for one product variant (for example, the Kubernetes docs) but the target doesn't exist in another variant (for example, the standalone docs) because the content is organized differently, wrap the offending sentence in a build-condition shortcode rather than removing it. Check the repo for an existing `conditional-text` shortcode and use it like:
125+
126+
```
127+
{{< conditional-text include-if="kubernetes" >}}For more information, see [...](...).{{< /conditional-text >}}
128+
```
129+
130+
This keeps the link visible where it works and silently drops it where it doesn't.
131+
132+
### Updating lychee config for false positives
133+
134+
When you confirm a class of false positives, update the shared `lychee.toml` exclude list so they don't reappear. Group the patterns with a comment explaining *why* (JS-rendered anchors, intentional short-form URLs, etc.) so future maintainers don't strip them as noise.
135+
136+
---
137+
138+
## Reporting back
139+
140+
After processing the report, give the user a structured summary. Group findings by outcome:
141+
142+
```
143+
## False positives
144+
- <link> — <why it's actually working> (added to lychee.toml exclude / suggest adding to lychee.toml exclude)
145+
146+
## Skipped — kept as redirect-as-intended
147+
- <link> — <why the redirect is intentional> (added to lychee.toml exclude / suggest adding)
148+
149+
## Needs human review
150+
- <link> in <file> — <why: couldn't determine new URL / content removed / cross-variant content gap / shortcode bug / etc.>
151+
152+
## Skipped — generated reference content
153+
- <N> links under reference/ directories
154+
```
155+
156+
Keep the summary concise. Do not include long lists of identical reference/ skips. Fixed links do not need to be reported individually unless the user specifically asks. If you spot a root-cause bug (for example a shortcode that produces broken URLs for certain inputs), call it out in "Needs human review" with a pointer to the file and the suggested fix.
157+
158+
---
159+
160+
## Don't
161+
162+
- Don't open a PR or push. Local edits only.
163+
- Don't edit files under `public/` — those are build output.
164+
- Don't edit generated reference pages even if you think you know the fix.
165+
- Don't guess new URLs. If you can't verify, flag for review.
166+
- Don't edit the thin content wrapper when the body is a reuse — edit the shared file.

.github/workflows/links.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,15 @@ jobs:
171171
name: link-checker-assets
172172
path: artifacts/*
173173

174+
- name: Write report to job summary
175+
if: hashFiles('artifacts/agentgateway-oss-links.md') != ''
176+
run: cat artifacts/agentgateway-oss-links.md >> "$GITHUB_STEP_SUMMARY"
177+
174178
- name: Fail check if errors exist
175179
if: github.event_name == 'pull_request'
176180
env:
177181
ERRORS: ${{ steps.link-stats.outputs.errors }}
178182
run: |
179-
cat artifacts/agentgateway-oss-links.md >> "$GITHUB_STEP_SUMMARY"
180183
if [ "${ERRORS:-0}" -gt 0 ]; then
181184
echo "Link checker found ${ERRORS} error(s). See artifacts for details."
182185
exit 1

assets/agw-docs/pages/about/custom-resources.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ To spin up a Gateway and manage its lifecycle, a gateway controller is used. The
2323
To configure routing, the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides several routing resources, such as an HTTPRoute and TCPRoute. These routes attach to a Gateway resource and define how incoming traffic is matched and forwarded to a backing destination.
2424

2525
* [HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/): The most commonly used route resource, that configures traffic routing for HTTP and HTTPS traffic.
26-
* [TCPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute): A resource to route TCP requests.
26+
* [TCPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#tcproute): A resource to route TCP requests.
2727

2828
While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides the functionality for basic request matching, redirects, rewrites, and header manipulation, it is missing more complex traffic management, resiliency, and security features, such as transformations, access logging, or route delegation.
2929

assets/agw-docs/pages/agentgateway/integrations/llm-clients-k8s/claude-code.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Configure [Claude Code](https://docs.anthropic.com/en/docs/claude-code), the AI coding CLI by Anthropic, to route LLM requests through your agentgateway proxy running in Kubernetes.
1+
Configure [Claude Code](https://code.claude.com/docs), the AI coding CLI by Anthropic, to route LLM requests through your agentgateway proxy running in Kubernetes.
22

33
## Before you begin
44

55
1. Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}).
6-
2. Install the [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) (`npm install -g @anthropic-ai/claude-code`).
7-
3. Get an Anthropic API key from the [Anthropic Console](https://console.anthropic.com).
6+
2. Install the [Claude Code CLI](https://code.claude.com/docs) (`npm install -g @anthropic-ai/claude-code`).
7+
3. Get an Anthropic API key from the [Anthropic Console](https://platform.claude.com).
88

99
## Get the gateway URL
1010

assets/agw-docs/pages/agentgateway/integrations/llm-clients-k8s/continue.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Configure [Continue](https://continue.dev/), the open-source AI code assistant for VS Code, to use agentgateway deployed in Kubernetes.
1+
Configure [Continue](https://www.continue.dev/), the open-source AI code assistant for VS Code, to use agentgateway deployed in Kubernetes.
22

33
## Before you begin
44

assets/agw-docs/pages/agentgateway/integrations/llm-clients-k8s/windsurf.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Configure [Windsurf](https://codeium.com/windsurf), the AI code editor by Codeium, to route requests to your LLM through your agentgateway proxy.
1+
Configure [Windsurf](https://windsurf.com/editor), the AI code editor by Codeium, to route requests to your LLM through your agentgateway proxy.
22

33
## Before you begin
44

assets/agw-docs/pages/agentgateway/integrations/llm-clients/claude-code.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Configure [Claude Code](https://docs.anthropic.com/en/docs/claude-code), the AI coding CLI by Anthropic, to route LLM requests through your agentgateway proxy.
1+
Configure [Claude Code](https://code.claude.com/docs), the AI coding CLI by Anthropic, to route LLM requests through your agentgateway proxy.
22

33
## Before you begin
44

55
1. {{< reuse "agw-docs/snippets/prereq-agentgateway.md" >}}
6-
2. Install the [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) (`npm install -g @anthropic-ai/claude-code`).
7-
3. Get an Anthropic API key from the [Anthropic Console](https://console.anthropic.com).
6+
2. Install the [Claude Code CLI](https://code.claude.com/docs) (`npm install -g @anthropic-ai/claude-code`).
7+
3. Get an Anthropic API key from the [Anthropic Console](https://platform.claude.com).
88

99
## Configure agentgateway
1010

assets/agw-docs/pages/agentgateway/integrations/llm-clients/continue.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Configure [Continue](https://continue.dev/), the open-source AI code assistant for VS Code, to route requests through agentgateway.
1+
Configure [Continue](https://www.continue.dev/), the open-source AI code assistant for VS Code, to route requests through agentgateway.
22

33
## Before you begin
44

assets/agw-docs/pages/agentgateway/integrations/llm-clients/windsurf.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
Configure [Windsurf](https://codeium.com/windsurf), the AI code editor by Codeium, to route requests to your LLM through your agentgateway proxy.
1+
Configure [Windsurf](https://windsurf.com/editor), the AI code editor by Codeium, to route requests to your LLM through your agentgateway proxy.
22

33
## Before you begin
44

55
1. {{< reuse "agw-docs/snippets/prereq-agentgateway.md" >}}
6-
2. Install [Windsurf](https://codeium.com/windsurf).
6+
2. Install [Windsurf](https://windsurf.com/editor).
77

88
## Example agentgateway configuration
99

assets/agw-docs/pages/agentgateway/llm/providers/anthropic.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,6 @@ Example output:
603603

604604
## Connect to Claude Code
605605

606-
To route Claude Code CLI traffic through agentgateway, see the [Claude Code integration guide]({{< link-hextra path="/integrations/llm-clients/claude-code" >}}).{{% conditional-text include-if="kubernetes" %}} For a full tutorial with prompt guards and observability, see the [Claude Code CLI proxy tutorial]({{< link-hextra path="/tutorials/claude-code-proxy" >}}).{{% /conditional-text %}}
606+
{{% conditional-text include-if="kubernetes,standalone" %}}To route Claude Code CLI traffic through agentgateway, see the [Claude Code integration guide]({{< link-hextra path="/integrations/llm-clients/claude-code" >}}).{{% /conditional-text %}}{{% conditional-text include-if="kubernetes" %}} For a full tutorial with prompt guards and observability, see the [Claude Code CLI proxy tutorial]({{< link-hextra path="/tutorials/claude-code-proxy" >}}).{{% /conditional-text %}}
607607

608608
{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}

0 commit comments

Comments
 (0)