| name | new-doc-page |
| description | Create a new documentation page for the Harness 3.0 docs site. Use when adding a new doc page, creating documentation, or when asked to add a page to the docs. Handles all three required file registrations and generates the page component. |
| argument-hint | <page-slug> <section-slug> [page-title] |
| allowed-tools | Read, Edit, Write, Grep, Glob, Bash(npx tsc --noEmit) |
Create a New Documentation Page
Create a new documentation page with slug $0 in section $1, with optional title $2.
You MUST complete all three registration steps plus create the component file. Missing any step will break navigation.
Step 1: Gather context
- Read
lib/docs-data.ts to understand the existing sections and find where to add the new item.
- Read
components/docs/page-content.tsx to see the import and registration patterns.
- If
$2 (title) is not provided, derive a readable title from the slug by converting kebab-case to Title Case.
Step 2: Register in lib/docs-data.ts
Add the new item to the correct section in the docSections array:
{
title: "<Page Title>",
slug: "<page-slug>",
description: "<Short description of what this page covers>",
badge: "new",
}
Then add TOC entries in the tocByPage record. Always include an "Overview" entry first, then add section entries based on the content plan:
"<page-slug>": [
{ title: "Overview", id: "overview" },
{ title: "Section Name", id: "section-id" },
],
Step 3: Register in components/docs/page-content.tsx
Add the import at the top with the other page imports:
import { PageNamePage } from "@/components/docs/pages/<page-slug>"
Add the entry in the pageComponents record (maintain alphabetical order by slug):
"<page-slug>": PageNamePage,
Naming conventions:
- File name:
<page-slug>.tsx (exception: if the slug conflicts with a reserved name like "settings", use <slug>-page.tsx)
- Export name: PascalCase of slug + "Page" (e.g.,
ci-steps โ CiStepsPage)
Step 4: Create the page component
Create the file at components/docs/pages/<page-slug>.tsx following this exact structure:
import { Separator } from "@/components/ui/separator"
import { CodeBlock } from "@/components/docs/code-block"
import { Callout } from "@/components/docs/callout"
import { Badge } from "@/components/ui/badge"
import { Clock } from "lucide-react"
interface PageNamePageProps {
onNavigate?: (section: string, item: string) => void
}
export function PageNamePage({ onNavigate }: PageNamePageProps) {
return (
<div className="space-y-0">
{/* Header */}
<header id="overview" className="mt-6 scroll-mt-20">
<div className="flex items-center gap-3">
<Badge variant="secondary" className="text-xs">
Section Category
</Badge>
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
<Clock className="h-3 w-3" />
<span>Last updated Mar 2026</span>
</div>
</div>
<h1 className="mt-3 text-balance text-3xl font-bold tracking-tight text-foreground lg:text-4xl">
Page Title
</h1>
<p className="mt-3 max-w-2xl text-pretty text-base leading-relaxed text-muted-foreground lg:text-lg">
Description paragraph explaining what this page covers.
</p>
</header>
<Separator className="my-8" />
{/* Each section MUST have id + scroll-mt-20 for TOC linking */}
<section id="section-id" className="scroll-mt-20">
<h2 className="text-xl font-semibold text-foreground">Section Title</h2>
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">
Section content.
</p>
</section>
<Separator className="my-8" />
</div>
)
}
Component usage rules
CodeBlock โ for YAML/code examples:
<CodeBlock code={`code here`} language="yaml" filename="pipeline.yaml" showLineNumbers={true} highlightLines={[2, 5]} />
Callout โ for info/warning/tip/success boxes:
<Callout type="info" title="Title" className="mt-4">Content here.</Callout>
Tables โ wrap in overflow container:
<div className="mt-4 overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-border">
<th className="px-3 py-2 text-left font-semibold text-foreground">Header</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
<tr className="border-b border-border">
<td className="px-3 py-2 font-medium text-foreground">Label</td>
<td className="px-3 py-2">Value</td>
</tr>
</tbody>
</table>
</div>
Bullet lists:
<ul className="mt-2 space-y-1.5 text-sm text-muted-foreground">
<li className="flex items-start gap-2">
<span className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-primary" />
Item text
</li>
</ul>
Inline code:
<code className="rounded bg-muted px-1.5 py-0.5 text-xs font-mono text-foreground">code</code>
Cross-page links โ use the onNavigate prop:
<span className="cursor-pointer text-primary hover:underline" onClick={() => onNavigate?.("section-slug", "page-slug")}>
Link text
</span>
External links:
<a href="https://..." target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1 text-primary hover:underline">
Link text <ExternalLink className="h-3 w-3" />
</a>
YAML convention
All Harness pipeline YAML examples MUST use the v1 schema:
- No
projectIdentifier, orgIdentifier, or identifier fields
- Flat stage types:
type: deploy or type: ci
- Steps use
with: (not spec:)
- Expression syntax:
${{ expression }} with snake_case
Step 5: Create markdown backup
Create a markdown backup file at docs/<section-slug>/<page-slug>.md.
The section-slug to directory mapping:
getting-started โ docs/getting-started/
pipeline-spec โ docs/pipeline-spec/
connectors โ docs/connectors/
secrets โ docs/secrets/
platform โ docs/platform/
harness-code โ docs/harness-code/
step-library โ docs/step-library/
agents โ docs/agents/
dashboards โ docs/dashboards/
roadmap โ docs/roadmap/
The markdown file must contain:
---
title: "Page Title"
description: "Short description"
section: "Section Name"
slug: "page-slug"
---
# Page Title
*Section Category | Last updated Mar 2026*
All page content converted to standard markdown...
Conversion from TSX to markdown:
- h1/h2/h3 โ
#/##/###
<CodeBlock> โ fenced code block with language (add filename as comment above if present)
<Callout type="info" title="Title"> โ > **Info: Title**\n> content
<Callout type="warning"> โ > **Warning: Title**
<Callout type="tip"> โ > **Tip: Title**
<Callout type="success"> โ > **Success: Title**
- Tables โ standard markdown tables
- Bullet lists โ
- item
- Inline
<code> โ backtick code
- Cross-page
onNavigate links โ [text](../section-slug/page-slug.md)
- External links โ
[text](url)
Step 6: Validate
- Run
npx tsc --noEmit to verify no type errors.
- Verify the TOC entry
id values exactly match the id attributes on sections in the page component.
- Verify the page is registered in all four locations (docs-data, page-content, component, markdown backup).
Critical rules
- Every
<section> must have both id and className="scroll-mt-20" for anchor linking
- The header section always uses
id="overview"
- Use
<Separator className="my-8" /> between sections
- Badge text in the header should match the parent section name
- The
"Last updated" date should be the current month and year
- Import only the Lucide icons you actually use
- Do NOT add unused imports