vcluster-docs-writer
Write and edit vCluster Docusaurus documentation. Use this skill when working with .mdx or .md files in the vcluster-docs repository. Handles vale linting, partials discovery, link validation, versioned docs, and release processes.
Best use case
vcluster-docs-writer is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Write and edit vCluster Docusaurus documentation. Use this skill when working with .mdx or .md files in the vcluster-docs repository. Handles vale linting, partials discovery, link validation, versioned docs, and release processes.
Teams using vcluster-docs-writer should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/vcluster-docs-writer/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How vcluster-docs-writer Compares
| Feature / Agent | vcluster-docs-writer | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Write and edit vCluster Docusaurus documentation. Use this skill when working with .mdx or .md files in the vcluster-docs repository. Handles vale linting, partials discovery, link validation, versioned docs, and release processes.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# vCluster Documentation Writer
Specialized knowledge and workflows for writing vCluster documentation in Docusaurus.
## Dependencies
When this skill is loaded, also invoke: `vcluster-brand:vcluster-brand`
## When to Use
Trigger when:
- Working in `/home/decoder/loft/vcluster-docs` repository
- User asks to write, edit, review, or fix documentation
- User mentions: vale, partials, doc links, versioned docs, releases
- User needs to discover partials, components, or code blocks
- User asks about vCluster terminology or style guidelines
## Quick Workflows
### Writing New Documentation
1. Review style guidelines in `references/style-guide.md`
2. Follow document template structure (Overview → How to use → Examples → Limitations)
3. Discover available resources:
```bash
scripts/discover_partials.sh # Find partials
scripts/detect_language.sh <file> # Get language identifier
scripts/generate_import.sh <path> # Generate import statement
```
4. Run vale for style checking:
```bash
scripts/run_vale.sh <file-path>
```
5. Verify links before committing (see Link Validation below)
See `references/style-guide.md` for complete writing guidelines.
### Editing Existing Documentation
1. **Check if file is versioned** (`vcluster_versioned_docs/version-*/`)
- ⚠️ **CRITICAL**: NEVER modify versioned docs unless explicitly requested
- Only update files in main `vcluster/` folder for current docs
2. Run vale before and after edits:
```bash
scripts/run_vale.sh <file-path>
```
3. Verify links if modified (see Link Validation below)
### Link Validation and Fixing
**Core principle**: Use relative file paths with `.mdx` extensions, NOT URL paths.
❌ **WRONG** (URL paths):
```markdown
[Pod Identity](/vcluster/integrations/pod-identity/eks-pod-identity)
```
✅ **CORRECT** (file paths with .mdx):
```markdown
[Pod Identity](../../../../third-party-integrations/pod-identity/eks-pod-identity.mdx)
```
**Debugging broken links efficiently:**
```bash
cd vcluster_versioned_docs/version-X.X.X/path/from/error/
grep -r "filename-from-error" . --include="*.mdx"
# Fix relative path in file that appears
```
See `references/link-formatting.md` for detailed examples and rules.
### Release Preparation
⚠️ **CRITICAL** before cutting new versioned docs release:
1. Check for problematic patterns:
```bash
grep -r "/vcluster/integrations\|/vcluster/deploy/security" vcluster_versioned_docs/version-X.X.X/
```
2. Fix absolute URL paths → relative file paths (common files listed in reference)
3. Clear caches before building:
```bash
rm -rf .docusaurus build node_modules/.cache
```
4. **NEVER run `npm run build`** - User runs when needed
See `references/release-checklist.md` for complete release workflow.
### Versioned Docs and lastVersion Routing
**Critical concept**: When `lastVersion` changes in `docusaurus.config.js`, URL routing changes.
```
lastVersion: "0.30.0" → /docs/vcluster/... routes to 0.30.0 content
/docs/vcluster/0.29.0/... routes to 0.29.0 content
```
**Key insight**: `/docs/vcluster/...` (no version) ALWAYS routes to `lastVersion` content.
**Why links break**:
1. Older versioned docs using unversioned paths resolve to new lastVersion
2. Cross-plugin links (vCluster→Platform or Platform→vCluster) resolve to each plugin's lastVersion
3. Path restructuring between versions causes 404s
**Version isolation principle**: Each version should link within itself:
```markdown
<!-- In 0.29.0 docs - CORRECT -->
[Link](../configure/something.mdx) <!-- relative file path -->
<!-- In 0.29.0 docs - RISKY (resolves to lastVersion) -->
[Link](/docs/vcluster/configure/something) <!-- unversioned URL -->
```
**Cross-plugin links (vCluster→Platform)**: Always resolve to Platform's lastVersion:
```markdown
<!-- These will break when Platform restructures paths -->
[Platform docs](/docs/platform/administer/monitoring/...)
<!-- After Platform 4.6.0, this became: -->
[Platform docs](/docs/platform/maintenance/monitoring/...)
```
**Fixing broken links after version release**:
```bash
# Find unversioned platform links that need updating
grep -r "/docs/platform/administer/\|/platform/api/" vcluster vcluster_versioned_docs --include="*.mdx"
# Bulk fix with sed
find vcluster vcluster_versioned_docs -name "*.mdx" \
-exec sed -i 's|/platform/old/path|/platform/new/path|g' {} \;
```
### Sidebar Navigation Conventions
Docusaurus sidebar categories can be made clickable (navigating to a page on click) in two ways. Both are banned — sidebar section labels must expand/collapse only.
**Anti-pattern 1: `link` field in `_category_.json`**
```json
// WRONG — do not add a link field
{
"label": "Deploy",
"position": 2,
"link": {
"type": "generated-index"
}
}
```
Remove the `link` field entirely. The `label` and `position` fields are sufficient.
**Anti-pattern 2: `README.mdx` as a folder index (general docs)**
Docusaurus automatically converts a `README.mdx` file into the category's landing page and makes the section label clickable — even without a `link` in `_category_.json`. Do not create `README.mdx` files as folder indices in general docs sections.
Instead, use `overview.mdx` with an explicit `slug:` that matches the directory URL:
```mdx
---
title: Networking
sidebar_label: Overview
sidebar_position: 0
slug: /configure/vcluster-yaml/networking
---
```
When converting an existing `README.mdx` to `overview.mdx`:
1. Add `slug:` matching the directory's URL (plugin-relative, no `/vcluster/` prefix).
2. Set `sidebar_label: Overview` — not the section name, to avoid duplication.
3. Migrate `sidebar_position` and `sidebar_class_name` out of the MDX frontmatter and into `_category_.json` as `position` and `className` respectively. The `_category_.json` controls the section label in the sidebar; the `overview.mdx` frontmatter controls only the child item.
4. Update any relative links inside the file that previously resolved from a directory URL — they now resolve from the slug URL.
**`_category_.json` structure for a folder that has an `overview.mdx`:**
```json
{
"label": "Networking",
"position": 3,
"className": "host-nodes private-nodes"
}
```
Do not add a `link` field.
**Exception: `vcluster/configure/vcluster-yaml/` uses `README.mdx`**
The `vcluster-yaml` section mirrors the structure of the `vcluster.yaml` config file — every folder is a yaml key. Labeling these pages "Overview" is semantically wrong because there is no `overview` key in the yaml. In this section only, use `README.mdx` (not `overview.mdx`) as the folder index. Docusaurus treats it as the category header click target; it does not appear as a named sidebar item. Do NOT set `sidebar_label: Overview` or `sidebar_position: 0` on these files — they are irrelevant once the file becomes the category index.
### PR Preview URLs
Preview links MUST point to actual changed pages, NOT the docs root.
Base: `https://deploy-preview-{PR}--vcluster-docs-site.netlify.app/docs`
Derive the path from the file location — version goes after product name:
- `docs/platform/install/x.mdx` → `/docs/platform/next/install/x`
- `docs/vcluster/deploy/x.mdx` → `/docs/vcluster/next/deploy/x`
- `versioned_docs/version-0.31/vcluster/deploy/x.mdx` → `/docs/vcluster/0.31/deploy/x`
- `versioned_docs/version-0.28/platform/api/x.mdx` → `/docs/platform/0.28/api/x`
The version marked as `lastVersion` in `docusaurus.config.ts` has NO version segment in the URL. For example, if platform `lastVersion` is `4.6.0`, then `versioned_docs/version-4.6.0/platform/install/x.mdx` → `/docs/platform/install/x`.
List a preview link for EVERY modified document in the PR body's Preview section.
### Backporting Assessment
New work typically lands in `docs/` (the `next` version). Before completing a PR, assess whether changes should also apply to released versions in `versioned_docs/`:
- **Backport**: Factual errors, broken links, typos — apply to relevant prior versions
- **Don't backport**: New feature documentation — only applies to `next`
- **When unclear**: Note in the PR description that backporting should be reviewed
When backporting: make the same changes in relevant `versioned_docs/version-X.XX/` folders and include preview links for those versions too.
### Integration Tests (BrowserStack)
Cross-browser tests for documentation rendering (mermaid diagrams, etc.).
**Location**: `tests/` directory
**Structure**:
```
tests/
├── specs/ # Test files go here
│ └── mermaid-rendering.spec.js
├── browserstack.yml # BrowserStack SDK config
├── playwright.config.js # Playwright config
└── package.json
```
**Creating new tests**:
1. Create spec file in `tests/specs/` with `.spec.js` extension
2. Use Playwright Test format:
```javascript
const { test, expect } = require('@playwright/test');
test.describe('Feature Name', () => {
test('description', async ({ page }) => {
await page.goto(process.env.TEST_URL || 'https://www.vcluster.com/docs/...');
// assertions
});
});
```
3. Tests run on 7 browser configs (Safari/Chrome/Firefox on macOS/Windows)
**Running tests**:
```bash
cd tests
npm run test:local # Local Safari only
npm run test:browserstack # All browsers via BrowserStack (needs credentials)
```
**CI**: Tests run automatically on PRs via `.github/workflows/integration-tests.yml`
### Partials and Components
**Quick commands:**
```bash
scripts/discover_partials.sh # List all partials
scripts/detect_language.sh file.yml # Get language for code blocks
scripts/generate_import.sh <path> <dir> # Generate import statement
```
**Import patterns:**
```jsx
// Code block with raw loader
import Code from '!!raw-loader!@site/docs/_code/example.yaml';
<CodeBlock language="yaml">{Code}</CodeBlock>
// Regular partial
import Partial from '@site/docs/_partials/example.mdx';
<Partial />
```
See `references/partials-guide.md` for complete patterns and troubleshooting.
## Critical Rules
### Never-Do
- ⚠️ **NEVER modify versioned docs** unless explicitly requested
- ⚠️ **NEVER run `npm run build`** (user runs when needed)
- ⚠️ **NEVER use URL paths for links** (use file paths with `.mdx`)
- ⚠️ **NEVER place admonitions inside JSX components** like `<Step>`
- ⚠️ **NEVER add a `link` field to `_category_.json`** — sidebar section labels must expand/collapse only, not navigate
- ⚠️ **NEVER create `README.mdx` as a folder index** in general docs sections — use `overview.mdx` with an explicit `slug:` instead. **Exception**: `vcluster/configure/vcluster-yaml/` uses `README.mdx` because every folder is a yaml key and "Overview" is semantically wrong there (see Sidebar Navigation Conventions)
### Always-Do
- ✅ **Always run vale** before finalizing documentation
- ✅ **Always use file paths with `.mdx` extension** for links
- ✅ **Always check vCluster terminology** in `references/vcluster-terms.md`
- ✅ **Always use relative paths** for versioned content
- ✅ **Always add descriptive comments** in YAML code blocks
## vCluster Terminology Quick Reference
Key terms (see `references/vcluster-terms.md` for complete guide):
- **vCluster**: The trademark (never "vClusters" - legally incorrect)
- **tenant clusters**: The clusters that vCluster creates ("virtual clusters" is retired); lowercase in prose
- **control plane cluster**: The cluster that hosts tenant cluster control planes ("host cluster" is retired); lowercase in prose
- **vCluster Pro**: Enhanced/paid tenant cluster with Pro functionality
- **vCluster Platform**: Management platform and UI for tenant clusters
- **vcluster**: The CLI command name
## Resources
### scripts/
- `discover_partials.sh` - Find all _partials, _fragments, _code directories
- `detect_language.sh` - Map file extension to language identifier
- `run_vale.sh` - Run vale linter with proper configuration
- `generate_import.sh` - Generate correct import statement
### references/
- `style-guide.md` - Complete writing style guide from CONTRIBUTING.md
- `release-checklist.md` - Critical rules for documentation releases
- `link-formatting.md` - Link formatting rules with examples
- `partials-guide.md` - Complete partials and components guide
- `mdx-components.md` - MDX/JSX component usage and admonition rules
- `vcluster-terms.md` - vCluster product terminology and namingRelated Skills
vcluster-docs-releaser
vCluster Documentation Release Skill
vcluster-docs-archiver
Archive End-of-Life vCluster documentation versions. Use this skill when creating EOL documentation branches for vCluster or Platform versions. Handles branch creation, Docusaurus configuration, link fixing, Netlify deployment, and main branch updates.
platform-docs-releaser
Platform Documentation Release Skill
k8s-compat-matrix
Manages the Kubernetes compatibility matrix data and React component. Use when adding/removing K8s versions, updating conformance test results, or documenting known issues.
docusaurus-upgrader
Upgrades Docusaurus to latest version in vCluster documentation. Use when upgrading Docusaurus packages from older to newer versions. Handles package updates, compatibility fixes, testing, and rollback procedures.
config-partials-generator
Generate MDX config reference partials from vCluster JSON schema. Use when automation is skipped for alpha releases or when manually refreshing config docs.
microsoft-docs
Query official Microsoft documentation to find concepts, tutorials, and code examples across Azure, .NET, Agent Framework, Aspire, VS Code, GitHub, and more. Uses Microsoft Learn MCP as the default, with Context7 and Aspire MCP for content that lives outside learn.microsoft.com.
writer
Document creation, format conversion (ODT/DOCX/PDF), mail merge, and automation with LibreOffice Writer.
docs-architect
Creates comprehensive technical documentation from existing codebases. Analyzes architecture, design patterns, and implementation details to produce long-form technical manuals and ebooks.
Cold Email Writer
Writes personalized cold emails that actually get replies
Policy Writer
Generate professional internal policies for any business function — HR, IT, finance, compliance, data privacy, acceptable use, and more.
Grant Writer
Write winning grant proposals and funding applications. Works for government grants (SBIR, Innovate UK, Horizon Europe), foundation grants, and corporate funding programs.