# Content Generation

Generate high-quality site content from any AI coding agent. The `/write` skill handles docs, blog posts, changelogs, roadmap updates, and general pages — with voice rules, structure templates, and quality checks built in.

## The /write skill

```
/write docs forms
/write blog Why static sites are making a comeback
/write changelog
/write roadmap --sync
/write page About Us
```

The first argument is the content type. Everything after is the topic. Accepted types:

| Type | Aliases | What it does |
| --- | --- | --- |
| `docs` | `doc` | Create or update documentation pages |
| `blog` | — | Write a blog post with a thesis and date line |
| `changelog` | `change` | Generate a changelog entry from git history |
| `roadmap` | — | Update the roadmap, optionally syncing from GitHub Issues |
| `page` | — | Write a general-purpose page (landing, about, etc.) |

When invoked mid-conversation with no arguments, `/write` assumes you want docs covering the work just completed. It summarizes what it understands and asks you to confirm.

### How it works

1. Gathers context — calls `sitemd_site_context` for site identity, existing pages, writing conventions, and type-specific state (current changelog version, roadmap sections)
2. Reads existing content of the same type to match tone
3. Writes the content following type-specific structure and voice rules
4. Creates or updates the page via MCP tools
5. Validates the result with `sitemd_content_validate`

### AI-optimized content structure

The `/write` skill generates content that is optimized for citation by AI search engines (ChatGPT, Perplexity, Gemini, Google AI Overviews) in addition to traditional search:

- **Question-based headings** — H2s are phrased as questions when the section answers one ("How does X work?" rather than "X Mechanics"). AI systems match user queries directly to headings.
- **Answer-first paragraphs** — every section opens with a direct, standalone sentence that works as an extracted citation. The answer comes first, then the explanation.
- **Freshness signals** — docs pages include `updated: YYYY-MM-DD` in frontmatter with today's date. Search engines and AI systems use this to assess content recency.
- **Verifiable data** — blog posts favor specific numbers, measurements, and comparisons over vague claims. AI systems prioritize content with concrete data points.

These conventions work alongside sitemd's [SEO features](/docs/seo) — structured data, llms.txt, markdown output, and AI crawler directives — to maximize visibility across both traditional and AI search.

### Cross-agent support

Skills are part of sitemd's [agent onboarding](/docs/agent-onboarding) system — a layered approach that teaches agents your site's structure, syntax, and writing conventions automatically.

The skill exists in three formats:

| Location | Agent coverage |
| --- | --- |
| `.claude/skills/write/SKILL.md` | Claude Code |
| `.agents/skills/write/SKILL.md` | Codex CLI, any SKILL.md scanner |
| `AGENTS.md` (Content Generation section) | Cursor, VS Code, Copilot, JetBrains, Aider |

All three encode the same procedures. The Claude Code version is the richest — it calls MCP tools directly. The cross-agent versions reference MCP tool names generically.

## Content MCP tools

Four tools for content generation, added to the [MCP server](/docs/mcp-server). Any MCP-capable agent can use them.

### sitemd_site_context

Get everything needed before writing — site identity, existing pages in the target group, writing conventions, and type-specific state.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `contentType` | yes | One of: `page`, `docs`, `blog`, `changelog`, `roadmap` |
| `topic` | no | Topic or subject for the content |
| `scope` | no | `"full"` (default) includes syntax reference, `"quick"` omits it for a smaller response |

**Returns:** Object with `site` (name, description, URL), `existingPages` (pages in target group), `conventions` (title suffix, date format), `currentState` (latest changelog version, roadmap sections), `groups`, `syntax` (full component syntax reference — omitted when `scope: "quick"`), and `guidance` (writing tips, group usage, pointers to `_schema` and the sitemd documentation).

### Editing pages directly

Update an existing page by editing `pages/{slug}.md` directly. Supports full replacement, frontmatter merging, prepending, or appending.

Use prepend for changelog entries (new version at the top). Use full replacement for roadmap updates. Edit frontmatter to toggle `draft: true`.

### Git history for changelogs

Run `git log` to get structured git history for changelog generation and doc gap detection.

Categorization uses commit message heuristics: messages starting with add/feat/new map to Added, fix/bug/patch to Fixed, remove/delete/drop to Removed, everything else to Changed.

Cross-reference changed source files against doc pages to detect gaps. If `engine/build/forms.js` changed in 8 commits but `pages/docs/forms.md` wasn't updated, it's a gap worth documenting.

### sitemd_content_validate

Quality-check a page against rules for its content type.

**Parameters:**

| Name | Required | Description |
| --- | --- | --- |
| `slug` | yes | Page slug to validate |

**Returns:** Object with `contentType` (auto-detected from group membership) and `checks` — an array of pass/fail results:

- Description under 160 characters
- Required frontmatter fields present
- No broken internal links
- Images have alt text
- Code blocks have language hints
- Type-specific: blog has date line, docs has sidebar config, changelog has valid version format

## Draft mode

Set `draft: true` in any page's frontmatter to mark it as a draft:

```yaml
---
title: Upcoming Feature
description: Documentation for the upcoming feature.
slug: /docs/upcoming-feature
draft: true
---
```

Draft pages behave differently by build mode:

| Behavior | Dev server | Production build |
| --- | --- | --- |
| Built to HTML | Yes | No |
| Visible in browser | Yes, with DRAFT banner | Excluded entirely |
| In sitemap | Yes | No |
| In group navigation | Yes | No |

Draft mode is the safety valve for auto-generated content. When automation creates a changelog entry or doc update, it can start as a draft so you review it before publishing.

## Content settings

Configure automation triggers in `settings/content.md`:

```yaml
---
# Auto-changelog: generate entries from git history
# Options: on-deploy, manual
autoChangelog: manual

# Auto-docs: detect code changes without matching doc updates
# Options: on-deploy, manual
autoDocs: manual

# GitHub integration for roadmap sync
# Set repo: sitemd config set content.githubRepo owner/repo
# Set token: sitemd config set content.githubToken ghp_xxx
# Options: github-issues, none
autoRoadmap: none

# Roadmap label mapping (GitHub issue labels to roadmap sections)
roadmapLabels:
  shipped: shipped, done, released
  inProgress: in-progress, wip, current
  planned: planned, next, backlog
---
```

### Auto changelog

When `autoChangelog` is set to `on-deploy`, the deploy flow generates a changelog entry from git history before building. The agent categorizes commits, determines the version bump (fixes = patch, features = minor), and prepends the entry to `pages/changelog.md`.

Run manually any time with `/write changelog`.

### Auto docs

When `autoDocs` is set to `on-deploy`, the build detects source files that changed without matching doc updates. The agent reads the changed code and updates the corresponding doc pages.

Run manually with `/write docs` (no topic) to trigger gap detection.

### Auto roadmap from GitHub

When `autoRoadmap` is set to `github-issues`, the roadmap syncs from GitHub Issues. Configure the repo and token:

```
sitemd config set content.githubRepo owner/repo
sitemd config set content.githubToken ghp_xxx
```

Issues are mapped to roadmap sections by label:

| GitHub signal | Roadmap section |
| --- | --- |
| Closed issues with shipped/done/released label | **Shipped** |
| Open issues with in-progress/wip label or current milestone | **In Progress** |
| Open issues with planned/next/backlog label | **Planned** |
| Issues with no matching labels | Skipped |

Labels are configurable via `roadmapLabels` in the settings. Shipped items are cross-referenced against the changelog — if a shipped issue has no changelog entry, the agent flags it.

Run manually with `/write roadmap --sync`.