with one click
docs
// Bootstrap, audit, or migrate a VitePress docs site (PRD/roadmap/file-map layout). Wires into admin runner and CLAUDE.md.
// Bootstrap, audit, or migrate a VitePress docs site (PRD/roadmap/file-map layout). Wires into admin runner and CLAUDE.md.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | docs |
| description | Bootstrap, audit, or migrate a VitePress docs site (PRD/roadmap/file-map layout). Wires into admin runner and CLAUDE.md. |
| user_invocable | true |
A docs site is one of three things at any given moment:
docs/ folder. Bootstrap the standard layout.docs/ has loose markdown but no VitePress, or has phase/task/roadmap files cluttering the root, or is missing universal files. Audit, propose migrations, and align it.docs/ matches the standard layout. Verify, optionally refresh stubs, and exit clean.This skill detects which case you're in and runs the right flow.
Don't read VitePress's node_modules/ source or its theme internals. The library works; the integration points are stable. Read its config and your own markdown ā that's it. If a build error references VitePress internals, the fix is almost always a markdown gotcha or the .mts rename, not a deep dive into VitePress.
The only files this skill should read or write:
package.json (for the docs:dev script)admin.toml (for the [commands.docs] entry, if admin is present)CLAUDE.md (for the Documentation section).gitignoredocs/ itselfdocs/
āāā .vitepress/config.mts # VitePress config (note .mts ā ESM-only; see ESM gotcha below)
āāā index.md # VitePress home/landing
āāā PRD.md # What this product is. The "spec."
āāā roadmap.md # Now / Next / Later / Deferred
āāā file-map.md # Concise repo navigation
Rationale: every project has a "what" (PRD), a "where next" (roadmap), and a "where things are" (file-map). These are the three load-bearing docs that decay fastest if not maintained.
docs/
āāā api.md # External API surface (HTTP, plugin API, GraphQL, library API, CLI)
āāā architecture/ # Multi-subsystem repos
ā āāā overview.md
ā āāā <subsystem>.md ...
āāā guide/ # End-user-facing surface
ā āāā getting-started.md
ā āāā <feature>.md ...
āāā development/ # Contributor-facing
āāā setup.md
āāā testing.md
āāā code-style.md
āāā troubleshooting.md
āāā deployment.md
| Folder/file | Trigger |
|---|---|
api.md | package.json declares "main" / "bin" / "exports" / peer/library deps; OR GraphQL / OpenAPI schema present (*.graphql, openapi.{yml,yaml,json}); OR plugin manifest pattern (<name>.yml next to package.json); OR CLI entry (bin/, cmd/ for Go, shebang scripts); OR HTTP server framework imported (Express / Fastify / Hono / Axum / etc.) |
architecture/ | 3+ top-level source folders, OR clearly multi-subsystem (web + iOS, frontend + backend, monorepo) |
guide/ | User-facing surface (web app, CLI tool, end-user product ā not a library) |
development/ | Git repo with > 1 contributor in history, OR CI configured, OR open-source (LICENSE + non-private remote) |
roadmap.md is a single file with four sections:
# Roadmap
> Direction, not task tracking. Promote items to GitHub issues once they're concrete enough to act on.
## Now
What's actively being worked on.
## Next
Next 1ā3 things on deck.
## Later
Things we want eventually.
## Deferred / won't fix
Things we considered and decided against, or punted indefinitely. Keep these so we don't re-litigate.
Don't create a docs/roadmap/ folder unless the user explicitly asks ā multi-track is the exception. If you find one during audit, propose collapsing back to a single file unless the project has 3+ active long-running tracks.
Every audit / bootstrap run ensures the project's CLAUDE.md has a Documentation section like this. If missing, add it. If present but stale (different file list, no update-when table), update it.
## Documentation
This project has a VitePress docs site under `docs/`. Run `./admin docs` (or `npm run docs:dev`) to read it on `http://localhost:5193`.
Keep these in sync as you work:
| File | Update when |
|---|---|
| `docs/PRD.md` | Product behavior, scope, or surface area changes |
| `docs/roadmap.md` | Direction shifts, an initiative ships, or a decision is deferred |
| `docs/file-map.md` | Major files/folders are added, removed, renamed, or moved |
| `docs/api.md` | (if exists) external API surface changes |
| `docs/architecture/*` | (if exists) subsystem behavior changes |
Don't write new top-level planning / phase / feature docs in `docs/` ā file a GitHub issue instead. `roadmap.md` is the only forward-looking doc.
Adjust the table to drop rows whose files don't exist (e.g., omit the api.md row in projects that don't have one).
Inspect the project:
docs/ exist?docs/.vitepress/config.mts (or .ts) exist?PRD.md, roadmap.md, file-map.md, index.md) exist?docs/*.md files exist? (For migration detection.)package.json have a docs:dev script? Is vitepress in devDependencies?admin.toml exist? Does it have [commands.docs]?CLAUDE.md exist? Does it have a ## Documentation section?Decide which flow:
| State | Flow |
|---|---|
No docs/ | Phase 2a ā Bootstrap |
docs/ exists, no .vitepress/ | Phase 2c ā Migrate |
| Both exist | Phase 2b ā Audit |
Run these in order:
Install VitePress ā npm add -D vitepress (or bun add, pnpm add, etc. ā match the project's package manager).
Apply opt-in heuristics to decide which folders/files to create. Tell the user which opt-ins matched and why.
Create the universal files:
docs/.vitepress/config.mts (note .mts ā see ESM gotcha)docs/index.md with layout: home frontmatterdocs/PRD.md ā stub with H1 + intro inviting the user to fill in product specdocs/roadmap.md ā stub with the four sections (Now / Next / Later / Deferred)docs/file-map.md ā generate from a quick scan of the project's top-level structureCreate opt-in scaffolds for whichever heuristics matched. Stub each new file with H1 + a one-line "TODO: fill in" so the user has a starting point.
Wire package.json ā add "docs:dev": "vitepress dev docs --port {DOCS_PORT}" (default port 5193, or main app port + 20 if a main app port exists). Do not add docs:build or docs:preview unless the project deploys docs ā heuristic: .github/workflows/* mentions Pages/Netlify/Vercel/vitepress build, OR package.json has gh-pages / docs-deploy script.
Wire admin.toml if present:
[commands.docs]
kind = "npm"
desc = "serve VitePress docs site with hot reload on http://localhost:NNNN"
run = "docs:dev"
Use kind = "npm" (not kind = "shell") ā this is the dedicated renderer that auto-detects npm vs bun (via bun.lockb), runs <pkg> run <script>, and produces standardized success/error output. The run field is just the npm script name, not the full npm run ... command.
Add "docs" to the order array after clean. Note that logs (registered automatically via [logs.*]) and any logs-aliasing utility commands should NOT appear in order ā the generator validates strictly and rejects unknown command names. Standard order shape: ["build", "dev", "deploy", "---", "test", "clean", "docs", "icons", "reload"] (omit any of these the project doesn't have).
Then run ~/.admin/init-admin --regenerate . --force-dirty and verify with ./admin --help.
Update project CLAUDE.md ā add the Documentation section.
Append to .gitignore if not already present:
docs/.vitepress/cache
docs/.vitepress/dist
Verify Phase 3.
Walk through this checklist. Apply mechanical fixes silently and report them in a summary; propose substantive changes with a diff.
Mechanical (apply, then report in summary):
docs/.vitepress/config.ts exists (not .mts), rename to .mts. The build will fail otherwise on CommonJS projects.docs/api-surface.md exists, rename to docs/api.md and update any references.docs/roadmap/ is a folder with only an index.md (or only one or two files), collapse to single docs/roadmap.md. Skip if the folder has 3+ initiative files (genuine multi-track).PRD.md / roadmap.md / file-map.md / index.md that don't exist..gitignore entries ā add cache/dist lines if missing.devDependencies, install.docs:dev script ā add if missing (port 5193 or main+20).admin.toml [commands.docs] ā if admin.toml exists and docs command is missing or has sub-targets, fix it (single shell command).CLAUDE.md Documentation section ā add if missing.Substantive (propose with diff, ask before applying):
PHASE_*.md, FUTURE_FEATURES.md, PROJECT_PLAN.md, tasks/, or any non-standard top-level docs/*.md that isn't part of the standard layout, propose:
api.md), propose creating it.CLAUDE.md update-when table ā if the Documentation section exists but is missing the update-when table, propose updating it to the standard shape.Report a summary at the end: what was applied mechanically, what was proposed, what's still pending.
Project has docs/ with markdown files but no VitePress installed. Bootstrap VitePress on top, categorize the existing markdown into the standard layout.
PRD.md / roadmap.md / file-map.md if they happen to exist with content).docs/*.md, propose where it belongs:
docs/architecture/<name>.mddocs/guide/<name>.mddocs/development/<name>.mdnpm run docs:dev &
DEV_PID=$!
sleep 4
kill $DEV_PID 2>/dev/null
wait $DEV_PID 2>/dev/null
Look for Local: http://localhost:NNNN/ in the output.npm run docs:build and confirm clean.admin.toml was wired, run ./admin docs for a few seconds and confirm it boots VitePress with HMR.After everything verifies clean, commit:
docs/ files, package.json, CLAUDE.md, .gitignore, admin.toml, generated ./adminBootstrap docs site, Audit docs and migrate legacy phase docs to issues, etc.)VitePress is ESM-only. If package.json has "type": "commonjs" (or no type field on older Node), naming the config config.ts fails the build with:
"vitepress" resolved to an ESM file. ESM file cannot be loaded by `require`
Always use .mts. The .mts extension forces TypeScript to treat the file as ESM regardless of the project's module type. Works whether the project is ESM or CommonJS.
If you find a project with config.ts that's been working (because the project is "type": "module"), still rename to .mts for consistency ā it's the standard.
{{ }} ā interpreted as Vue template syntax, even inside backticks. Wrap with <code v-pre>{{ }}</code> or escape the braces.outline: deep frontmatter ā pages with H3+ headings need this to show full TOC..md ā use /guide/getting-started, not /guide/getting-started.md.layout: home frontmatter.[commands.docs] looks like in admin.toml[commands.docs]
kind = "npm"
desc = "serve VitePress docs site with hot reload on http://localhost:5193"
run = "docs:dev"
kind = "npm" is the dedicated renderer ā auto-detects npm vs bun, runs <pkg> run <script>, produces standardized output. Don't use kind = "shell" with run = "npm run docs:dev" ā that bypasses the renderer's lockfile detection and consistent error reporting.
Single command. No sub-targets. No docs build, no docs preview ā those are noise for local viewing. Add "docs" to the order array between clean and the utility commands (icons, reload). Then ~/.admin/init-admin --regenerate . --force-dirty.
If the project deploys docs (rare), add separate [commands.docs-build] / [commands.docs-deploy] rather than nesting under docs.
Don't, for docs. Actions ([actions.X]) are reusable building blocks for multi-step commands or shared infrastructure between several commands ā e.g. an apple archetype's build-ios action that gets invoked by both [commands.build.ios] and [commands.dev.ios] sub-targets. A single npm script invocation has neither shape, so kind = "npm" directly on the command is correct. Only reach for an action if you find yourself wanting to call the same docs operation from multiple commands.
docs/.vitepress/config.mtsimport { defineConfig } from 'vitepress'
export default defineConfig({
title: '{Project Name} Docs',
description: '{One-line description}',
cleanUrls: true,
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide/getting-started' },
{ text: 'Architecture', link: '/architecture/overview' },
{ text: 'Development', link: '/development/setup' },
{ text: 'Reference', link: '/PRD' },
],
sidebar: {
'/guide/': [{ text: 'Guide', items: [/* ... */] }],
'/architecture/': [{ text: 'Architecture', items: [/* ... */] }],
'/development/': [{ text: 'Development', items: [/* ... */] }],
'/': [
{
text: 'Reference',
items: [
{ text: 'Product spec (PRD)', link: '/PRD' },
{ text: 'Roadmap', link: '/roadmap' },
{ text: 'File map', link: '/file-map' },
// { text: 'API surface', link: '/api' }, // if exists
],
},
],
},
search: { provider: 'local' },
socialLinks: [{ icon: 'github', link: '{repo URL or omit}' }],
editLink: {
pattern: '{repo URL}/edit/main/docs/:path',
text: 'Edit this page on GitHub',
},
},
vite: {
server: { host: '0.0.0.0', port: 5193 },
},
})
Adjust nav / sidebar based on which opt-in folders the project has. Drop the api, architecture/, guide/, development/ entries if those folders don't exist.