Skip to content

Commit 8d36638

Browse files
authored
Merge branch 'main' into danny/pricing-faq-updates
2 parents 31f9aeb + a9de1f4 commit 8d36638

8 files changed

Lines changed: 325 additions & 400 deletions

File tree

.agents/skills/docs-seo-audit/SKILL.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ name: docs-seo-audit
33
description: >-
44
Audit docs.warp.dev for SEO issues like duplicate titles, missing meta
55
descriptions, title length problems, and H1 tag issues. Crawls the live
6-
sitemap, generates a report, and fixes issues in the source markdown. Use
6+
sitemap, generates a report, and fixes issues in the source files. Use
77
when asked to check SEO, fix duplicate titles, audit meta tags, improve
88
search rankings, or run an SEO check on the docs site.
99
---
1010

1111
# SEO Audit
1212

13-
Crawl the live docs.warp.dev sitemap to find SEO issues and fix them in the source markdown files.
13+
Crawl the live docs.warp.dev sitemap to find SEO issues and fix them in the source files.
1414

1515
## Running the audit
1616

@@ -48,7 +48,7 @@ The JSON report contains:
4848

4949
Each issue includes:
5050
- `url` — The live page URL
51-
- `source_file` — The local markdown file (if `--repo-root` was provided)
51+
- `source_file` — The local source file (if `--repo-root` was provided)
5252
- `severity``error` (must fix), `warning` (should fix), or `info` (nice to fix)
5353
- `type` — Issue category (see below)
5454
- `message` — Human-readable description
@@ -145,6 +145,7 @@ Some page titles are intentionally short or specific and must **not** be changed
145145
- **`src/content/docs/terminal/windows/split-panes.mdx`** (`Split panes`) — Same rationale: the section header disambiguates the terminal context. The `title_too_short` warning is intentionally suppressed. Do not rename to "Terminal split panes".
146146
- **`src/content/docs/terminal/windows/tab-configs.mdx`** (`Tab Configs`) — Same rationale: the section header disambiguates the terminal context. Additionally, "Tab Configs" is a proper feature name and should not be prefixed. The `title_too_short` warning is intentionally suppressed. Do not rename to "Terminal Tab Configs".
147147
- **`src/content/docs/terminal/sessions/index.mdx`** (`Sessions`) — The sidebar section header ("Sessions") already provides terminal context. The `title_too_short` warning is intentionally suppressed. Do not rename to "Terminal sessions".
148+
- **`src/content/docs/reference/cli/artifacts.mdx`** (`Artifacts`) — The Reference > CLI section provides context, and "Artifacts" matches the `oz artifact` resource that the page documents. The `title_too_short` warning is intentionally suppressed.
148149

149150
When the audit flags these pages for `title_too_short`, exclude them from your fix list and include a note in your report explaining they are intentional exceptions.
150151

@@ -244,7 +245,7 @@ If instructed to send a report to Slack, post a summary after the audit complete
244245

245246
**Categorizing issues in the summary:** Before composing the message, cross-reference every issue against the title exceptions list above and check whether the issue has a local source file. Classify each issue into exactly one bucket:
246247
- **Fixed** — issues you resolved in this run
247-
- **Unfixable** — issues with no local source file (e.g., auto-generated API pages)
248+
- **Unfixable** — issues with no local source file
248249
- **Allowlisted** — issues that match a title exception entry (these are intentional, not problems)
249250
- **Remaining** — everything else (genuine issues that still need attention)
250251

@@ -261,7 +262,7 @@ Only include a section in the Slack message if its count is > 0. Never list allo
261262
• Trimmed 3 overly long descriptions to ≤160 chars
262263
263264
*Unfixable (<count>):*
264-
• <N> pages missing meta descriptions (auto-generated, no local source)
265+
• <N> pages missing meta descriptions (no local source)
265266
266267
*Allowlisted (<count>):*
267268
• <page1>, <page2>, <page3> (intentionally short titles)
@@ -287,7 +288,7 @@ PR: <pr_url>
287288
<total_pages> pages scanned | <total_issues> issues found (<errors> errors, <warnings> warnings, <info> info)
288289
289290
*Unfixable (<count>):*
290-
• <N> pages missing meta descriptions (auto-generated, no local source)
291+
• <N> pages missing meta descriptions (no local source)
291292
292293
*Allowlisted (<count>):*
293294
• <page1>, <page2> (intentionally short titles)

.agents/skills/docs-seo-audit/scripts/seo_audit.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,15 @@ def extract_seo(url):
192192
# ---------------------------------------------------------------------------
193193

194194
def url_to_source_path(url, repo_root):
195-
"""Best-effort mapping from a live URL to the local markdown source file.
195+
"""Best-effort mapping from a live URL to the local source file.
196196
197197
Astro Starlight serves content from src/content/docs/. URL paths map
198198
directly to that directory. Files use .mdx (preferred) or .md extensions,
199199
and directory landing pages are index.mdx (not README.md).
200200
201+
Standalone Astro routes are served from src/pages/ and can be edited
202+
directly even when their content is generated from a spec or runtime data.
203+
201204
Returns the relative path from repo_root, or None if no file is found.
202205
"""
203206
from urllib.parse import urlparse
@@ -225,6 +228,20 @@ def url_to_source_path(url, repo_root):
225228
candidate = os.path.join(base, path, "index" + ext)
226229
if os.path.isfile(candidate):
227230
return os.path.relpath(candidate, repo_root)
231+
# Standalone Astro routes live outside Starlight content in src/pages/.
232+
# This maps pages like /api/ -> src/pages/api.astro and
233+
# /openapi.yaml -> src/pages/openapi.yaml.ts so generated docs shells
234+
# are treated as locally fixable when their source exists.
235+
pages_base = os.path.join(repo_root, "src", "pages")
236+
for ext in (".astro", ".ts", ".js", ".tsx", ".jsx"):
237+
candidate = os.path.join(pages_base, path + ext)
238+
if os.path.isfile(candidate):
239+
return os.path.relpath(candidate, repo_root)
240+
241+
for ext in (".astro", ".ts", ".js", ".tsx", ".jsx"):
242+
candidate = os.path.join(pages_base, path, "index" + ext)
243+
if os.path.isfile(candidate):
244+
return os.path.relpath(candidate, repo_root)
228245

229246
return None
230247

src/components/WarpTopbar.astro

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
/**
33
* Slim Warp brand topbar for standalone pages that don't sit inside Starlight
4-
* (currently just `/api`). Renders the Warp wordmark + a breadcrumb + a small
5-
* nav so the page reads as part of the same surface as the docs.
4+
* (currently just `/api`). Renders the Warp wordmark + docs breadcrumb + a
5+
* small nav so the page reads as part of the same surface as the docs.
66
*
77
* The host page must reserve `--warp-topbar-height` (3.5rem by default) at
88
* the top of the viewport — see `src/pages/api.astro` where the same value
@@ -44,23 +44,21 @@ const {
4444
---
4545

4646
<header class="warp-topbar" role="banner">
47-
{/* Wordmark links to warp.dev (matches CustomSiteTitle.astro on Starlight
48-
pages). Users still get to docs root via the explicit "← Docs" link in
49-
the right nav below. */}
50-
<a href="https://warp.dev" class="warp-topbar__home" aria-label="Visit warp.dev">
51-
<span class="warp-topbar__logo warp-topbar__logo--dark" aria-hidden="true" set:html={logoDark} />
52-
<span class="warp-topbar__logo warp-topbar__logo--light" aria-hidden="true" set:html={logoLight} />
47+
<div class="warp-topbar__left">
48+
{/* Wordmark links to warp.dev (matches CustomSiteTitle.astro on Starlight
49+
pages). Users get to docs root via the adjacent "← Docs" breadcrumb. */}
50+
<a href="https://warp.dev" class="warp-topbar__home" aria-label="Visit warp.dev">
51+
<span class="warp-topbar__logo warp-topbar__logo--dark" aria-hidden="true" set:html={logoDark} />
52+
<span class="warp-topbar__logo warp-topbar__logo--light" aria-hidden="true" set:html={logoLight} />
53+
</a>
54+
<a href="/" class="warp-topbar__docs">
55+
<span>Docs</span>
56+
</a>
5357
<span class="warp-topbar__sep" aria-hidden="true">/</span>
5458
<span class="warp-topbar__crumb">{crumb}</span>
55-
</a>
59+
</div>
5660
<div class="warp-topbar__right">
5761
<nav class="warp-topbar__nav" aria-label="Site">
58-
<a href="/" class="warp-topbar__link">
59-
<svg aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
60-
<path d="M19 12H5"/><path d="m12 19-7-7 7-7"/>
61-
</svg>
62-
<span>Docs</span>
63-
</a>
6462
{links.map((link) => (
6563
<a
6664
href={link.href}
@@ -123,19 +121,24 @@ const {
123121
font-family: var(--scalar-font, 'Inter', sans-serif);
124122
color: var(--scalar-color-1, #fafafa);
125123
}
126-
.warp-topbar__home {
124+
.warp-topbar__left {
127125
display: inline-flex;
128126
align-items: center;
129127
gap: 0.625rem;
128+
min-width: 0;
129+
}
130+
.warp-topbar__home {
131+
display: inline-flex;
132+
align-items: center;
130133
text-decoration: none;
131134
color: inherit;
132-
min-width: 0;
133135
padding: 0.25rem 0.375rem;
134136
margin-left: -0.375rem;
135137
border-radius: var(--sl-radius-md);
136138
}
137139
.warp-topbar__home:hover { background: var(--scalar-background-2); }
138-
.warp-topbar__home:focus-visible {
140+
.warp-topbar__home:focus-visible,
141+
.warp-topbar__docs:focus-visible {
139142
outline: 2px solid var(--scalar-color-accent);
140143
outline-offset: 2px;
141144
}
@@ -169,6 +172,23 @@ const {
169172
overflow: hidden;
170173
text-overflow: ellipsis;
171174
}
175+
.warp-topbar__docs {
176+
display: inline-flex;
177+
align-items: center;
178+
gap: 0.375rem;
179+
padding: 0 0.125rem;
180+
text-decoration: none;
181+
color: var(--scalar-color-3);
182+
font-size: 0.8125rem;
183+
font-weight: 500;
184+
line-height: 1.25;
185+
transition: color 0.15s ease;
186+
white-space: nowrap;
187+
border-radius: var(--sl-radius-xs);
188+
}
189+
.warp-topbar__docs:hover {
190+
color: var(--scalar-color-1);
191+
}
172192
/* Right group wraps the nav and the theme select so the topbar's
173193
`justify-content: space-between` keeps the home/crumb pinned left and
174194
the whole right cluster pinned right. */

0 commit comments

Comments
 (0)