Instructions for AI coding agents working with this repository.
CLAUDE.md is a symlink to this file. Edit AGENTS.md; never edit CLAUDE.md.
Documentation site for Kubedoop Data Platform (https://kubedoop.dev), built with
Docusaurus 3 and deployed to GitHub Pages. Bilingual: English
(en, default) and Chinese (zh-Hans).
This repository contains documentation only — no Kubedoop product code. The Operators it documents live in sibling repositories under https://github.com/zncdatadev.
- Framework: Docusaurus 3.10 (React 19, TypeScript 5.8)
- Package manager: npm. The lockfile is committed — use
npm ci, notnpm install - Node:
>=18perpackage.json; CI runs 22 - Deployment: GitHub Pages via the
gh-pagesbranch, published by CI on main pushes
docs/ # English documentation source (default locale)
i18n/zh/docusaurus-plugin-content-docs/current/ # Chinese documentation source
i18n/en/, i18n/zh/ # UI-string translations (generated, not prose)
src/ # React components and custom CSS
static/ # Static assets (images, favicons, CNAME)
docusaurus.config.ts # Site config (navbar, footer, i18n, markdown, themes)
sidebars.ts # Sidebar navigation structure
.markdownlint.yml # Markdown rule config
.github/workflows/gh-page.yml # CI: lint, build, deploy
One command mirrors CI:
npm run verify # lint:md + typecheck + build (both locales)Or step by step:
npm ci # install exactly what the lockfile pins
npm run lint:md # markdownlint over *.md, docs/**, i18n/**
npm run typecheck # tsc (noEmit comes from @docusaurus/tsconfig)
npm run build # production build, en + zh-Hans
npm start # dev server, hot reload, default locale onlynpm run verify passing is the bar for "done". Do not report a change as complete
without running it, and do not tick a PR checklist box you did not actually run.
Use the repo's pinned markdownlint, not a global one. markdownlint-cli2 is a
devDependency pinned to an exact version and npm run lint:md uses it. Newer versions
enforce rules this repo has never enforced: 0.23 adds MD060 (table-column-style),
which flags roughly 46 tables that CI considers clean. npx markdownlint-cli2 without a
version pulls the latest and will send you fixing violations that do not exist.
"Max 200 characters" is not literal. MD013 runs with strict: false, which exempts
lines having no whitespace past the limit — an unbreakable long line (a URL, a long word)
is not a violation. Do not rewrap prose to satisfy a rule that is not firing. Ask
npm run lint:md, do not count characters.
Do not measure line length in bytes. MD013 counts characters. awk 'length($0)'
counts bytes, so CJK prose (3 bytes per character) looks 3x longer than it is and
produces phantom violations.
Mermaid cannot be verified from build output. Diagrams render client-side, so the SSR
HTML holds an empty container either way. grep language-mermaid build/... returning 0
only proves the fence was intercepted, not that anything drew. To confirm a diagram
renders, load the page in a browser and look for .docusaurus-mermaid-container svg.
13 of 24 pages are empty or single-heading placeholders. Check before editing:
find docs -name '*.md' -size -100c | sort # the placeholdersTreat a placeholder as "not written yet" rather than a page to patch around.
Every file in docs/ has a counterpart at the same relative path under
i18n/zh/docusaurus-plugin-content-docs/current/. They currently match 1:1. Adding a
page in one language only breaks the convention silently: Docusaurus falls back to the
English source, so the build still passes.
diff <(cd docs && find . -name '*.md' | sort) \
<(cd i18n/zh/docusaurus-plugin-content-docs/current && find . -name '*.md' | sort)docs/developer-manual/first-commiter.md and docs/developer-manual/develop-guideline.md
hold Chinese prose inside the English tree, and first-commiter.md is byte-identical
to its zh counterpart. Write new pages in the language of the tree they live in.
-
English goes in
docs/, Chinese ini18n/zh/docusaurus-plugin-content-docs/current/ -
Filenames are kebab-case (
service-discovery.md) -
Add both languages in the same change
-
Check whether the sidebar needs an entry (see below)
-
After adding UI strings, regenerate translations:
npm run write-translations -- --locale zh-Hans
The
--separator is required. Without it npm swallows--localeand passes a barezhto docusaurus as a site directory, failing withENOENT ... lstat '<repo>/zh'.
Start from docs/operators/_template.md, which defines the standard sections: Overview,
Prerequisites, Quick Start, Configuration, Advanced, Troubleshooting, Clean Up, Related
Links. Copy it into both language trees.
sidebars.ts mixes hand-written entries with autogenerated blocks, so whether you must
touch it depends on where the page lands:
| Page location | Sidebar entry |
|---|---|
core-concepts/*/, operators/, developer-manual/, reference/, user-manual/environment/ |
Automatic (autogenerated) |
Repository top level and quick-start/ |
Manual — add it to sidebars.ts |
- Fenced code blocks need a language hint; use
textfor plain output (MD040) - Mermaid diagrams use fenced blocks with the
mermaidhint. Rendering is wired up indocusaurus.config.ts(markdown.mermaidplus@docusaurus/theme-mermaid), with the diagram theme mapped to the site colour mode - Prefer relative links for internal references (
../core-concepts/...) onBrokenLinks: 'throw'— a broken internal link fails the build
- Default locale
en, second localezh-Hans zh-Hansis the locale key;zhis only the URL path, set ini18n.localeConfigs['zh-Hans'].path. Never usezhas a locale keynpm startserves the default locale only — usenpm run buildto exercise both
<type>(<scope>): <subject>
Types: feat, fix, docs, style, refactor, test, chore
Example: docs(operators): add kafka-operator documentation
Use the body to explain why when the reason is not obvious from the diff.
.github/workflows/gh-page.yml:
| Job | Runs on | Does |
|---|---|---|
| Lint | PRs and main pushes | npm run lint (markdownlint + tsc) |
| Build | PRs only | npm run build, both locales |
| Deploy to GitHub Pages | main pushes only | build, then publish to gh-pages |
CI invokes the same npm scripts you run locally, so a local npm run verify passing
should mean CI passes.
Fork-based, with git worktrees for parallel tasks.
git clone https://github.com/<your-username>/docs.git
cd docs
git remote add upstream https://github.com/zncdatadev/docs.git- Sync:
git fetch upstream && git switch main && git merge --ff-only upstream/main - Branch off upstream main — see naming below
- Optional worktree:
git worktree add ../docs-<task> -b <branch-name> - Develop, then run
npm run verify - Push to your fork:
git push -u origin <branch-name> - Open a PR against
zncdatadev/docsmain - All CI checks must pass; one reviewer approval is required
- Clean up after merge:
git worktree remove <path>and delete the branch
Branch every PR off upstream main, never off another open PR's branch. A stacked PR
carries its parent's commits, and if the two merge out of order the same change lands
twice. This has already happened here: #35 was stacked on #33, both merged, and
docusaurus.config.ts ended up with duplicate markdown and themes keys — which broke
tsc on main and blocked every deploy until #36. If a change depends on another, wait
for the parent to merge, then rebase onto the new main.
| Type | Format | Example |
|---|---|---|
| New feature | feature/<scope>-<desc> |
feature/kafka-rebalance |
| Bug fix | fix/<scope>-<desc> |
fix/hdfs-memory-leak |
| Documentation | docs/<desc> |
docs/add-trino-operator |
| Refactor | refactor/<scope>-<desc> |
refactor/operator-go-api |
| Chore, deps, CI | chore/<desc> |
chore/upgrade-k8s-0.36 |
## Summary
Brief description of the change.
## Changes
- Change 1
- Change 2
## Testing
- [ ] `npm run verify` passes (lint + typecheck + build, both locales)
- [ ] New pages added to both `docs/` and the `zh` tree
- [ ] New pages appear in the sidebar
## Related Issues
Link to related issues or task IDs.Record what you actually ran. An honest note about what was skipped is worth more than a ticked box that nobody verified.