diff --git a/.github/workflows/gh-page.yml b/.github/workflows/gh-page.yml index c9ea82e..61e468c 100644 --- a/.github/workflows/gh-page.yml +++ b/.github/workflows/gh-page.yml @@ -1,72 +1,89 @@ -# .github/workflows/deploy.yml - name: gh-page -on: [push, pull_request] +on: + # Branch pushes are covered by the pull_request trigger; restricting push to + # main keeps forks from running the whole workflow on every branch push. + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + # Superseded PR runs are worth cancelling; a deploy in flight is not. + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: + contents: read jobs: - markdown-lint: - name: Markdown Lint + lint: + name: Lint runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 with: - fetch-depth: 0 - - name: markdownlint-cli2-action - uses: DavidAnson/markdownlint-cli2-action@v18.0.0 - with: - globs: | - *.md - docs/**/*.md - i18n/**/*.md - - typescript-lint: - name: TypeScript Lint + node-version: '22' + cache: npm + - name: Install Dependencies + run: npm ci + - name: Markdown and TypeScript Lint + # Same command contributors run locally, so CI cannot disagree with them + # about which markdownlint version or globs apply. + run: npm run lint + + build: + name: Build + # On main the deploy job builds the site; building twice would be waste. + if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 with: + # showLastUpdateAuthor/showLastUpdateTime read git history. Without the + # full history every page reports the same last-updated date. fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' + cache: npm - name: Install Dependencies - run: npm install - - name: TypeScript Lint - run: npm run typecheck + run: npm ci + - name: Build Docusaurus site + run: npm run build deploy: - needs: - - markdown-lint - - typescript-lint name: Deploy to GitHub Pages + if: github.event_name == 'push' + needs: + - lint runs-on: ubuntu-latest permissions: contents: write concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: deploy-gh-pages + cancel-in-progress: false steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - - - name: Install dependencies - run: npm install - - - name: Build Docusaurus site - run: npm run build - - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }} - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + - name: Install Dependencies + run: npm ci + - name: Build Docusaurus site + run: npm run build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build diff --git a/AGENTS.md b/AGENTS.md index 2891142..2371277 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,85 +2,161 @@ Instructions for AI coding agents working with this repository. +`CLAUDE.md` is a symlink to this file. Edit `AGENTS.md`; never edit `CLAUDE.md`. + ## Project Overview -This is the documentation site for **Kubedoop Data Platform** (), -built with [Docusaurus 3](https://docusaurus.io/). The site is deployed to GitHub -Pages and supports both English and Chinese (zh-Hans). +Documentation site for **Kubedoop Data Platform** (), built with +[Docusaurus 3](https://docusaurus.io/) 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 . ## Tech Stack - **Framework**: Docusaurus 3.10 (React 19, TypeScript 5.8) -- **Package Manager**: npm -- **Deployment**: GitHub Pages (`gh-pages` branch) +- **Package manager**: npm. The lockfile is committed — use `npm ci`, not `npm install` +- **Node**: `>=18` per `package.json`; CI runs 22 +- **Deployment**: GitHub Pages via the `gh-pages` branch, published by CI on main pushes ## Repository Structure ```text -docs/ # English documentation source -i18n/zh/docusaurus-plugin-content-docs/current/ # Chinese documentation source -src/ # React components and custom CSS -docusaurus.config.ts # Site configuration (navbar, footer, i18n, plugins) -sidebars.ts # Sidebar navigation structure -static/ # Static assets (images, favicons) +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 ``` -## Common Commands +## Verify Before Claiming Done + +One command mirrors CI: ```bash -npm install # Install dependencies -npm run build # Production build (en + zh-Hans) -npm start # Local dev server with hot reload -npm run typecheck # TypeScript type checking (npx tsc --noEmit) +npm run verify # lint:md + typecheck + build (both locales) ``` -## Development Rules +Or step by step: + +```bash +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 only +``` + +`npm 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. + +### Traps that have already cost time here + +**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. -### Before Submitting a PR +**"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. -1. Run `npm run build` and ensure it succeeds for both locales -2. Run `npx tsc --noEmit` and ensure no TypeScript errors -3. Check for markdown lint issues — no line should exceed 200 characters -4. Verify new pages appear correctly in the sidebar (`sidebars.ts`) +**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. -### Adding Documentation +**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`. -- **English docs**: place in `docs/` directory -- **Chinese docs**: place in `i18n/zh/docusaurus-plugin-content-docs/current/` -- Filenames use kebab-case (e.g., `service-discovery.md`) -- After adding Chinese docs, run `npm run write-translations -- --locale zh-Hans` - (the `--` separator is required, otherwise npm swallows `--locale` and the - bare `zh` is read as a site directory) +## Documentation Content -### Sidebar Updates +### Current state: early skeleton -All sidebar navigation is defined in `sidebars.ts`. New documentation pages -must be added to the appropriate category in this file to appear in the nav. +**13 of 24 pages are empty or single-heading placeholders.** Check before editing: -### i18n Notes +```bash +find docs -name '*.md' -size -100c | sort # the placeholders +``` + +Treat a placeholder as "not written yet" rather than a page to patch around. + +### The en and zh trees must mirror each other exactly + +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. + +```bash +diff <(cd docs && find . -name '*.md' | sort) \ + <(cd i18n/zh/docusaurus-plugin-content-docs/current && find . -name '*.md' | sort) +``` -- Default locale: `en` -- Second locale: `zh-Hans` (BCP 47 compliant) -- Locale configs are in `docusaurus.config.ts` under `i18n.localeConfigs` -- Do NOT use `zh` as a locale key — use `zh-Hans` (Docusaurus 3.10+ requirement) +### Known inconsistency — do not copy it -### Markdown Rules +`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. -- Max line length: 200 characters -- Use fenced code blocks with language hints (`yaml`, `bash`, `typescript`) -- For Mermaid diagrams, use fenced blocks with `mermaid` language hint +### Adding a page + +- English goes in `docs/`, Chinese in `i18n/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: + + ```bash + npm run write-translations -- --locale zh-Hans + ``` + + The `--` separator is required. Without it npm swallows `--locale` and passes a bare + `zh` to docusaurus as a site directory, failing with `ENOENT ... lstat '/zh'`. + +### New Operator pages + +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. + +## Sidebar + +`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` | + +## Markdown Rules + +- Fenced code blocks need a language hint; use `text` for plain output (`MD040`) +- Mermaid diagrams use fenced blocks with the `mermaid` hint. Rendering is wired up in + `docusaurus.config.ts` (`markdown.mermaid` plus `@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 -### Operator Documentation Template +## i18n Notes -When creating documentation for a new Operator, use the template at -`docs/operators/_template.md` as a starting point. The template defines -the standard sections: Overview, Prerequisites, Quick Start, Configuration, -Advanced, Troubleshooting, Clean Up, Related Links. +- Default locale `en`, second locale `zh-Hans` +- `zh-Hans` is the **locale key**; `zh` is only the URL **path**, set in + `i18n.localeConfigs['zh-Hans'].path`. Never use `zh` as a locale key +- `npm start` serves the default locale only — use `npm run build` to exercise both ## Commit Message Conventions -Follow [Conventional Commits](https://www.conventionalcommits.org/): +[Conventional Commits](https://www.conventionalcommits.org/): ```text (): @@ -90,41 +166,52 @@ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` Example: `docs(operators): add kafka-operator documentation` -## CI Checks +Use the body to explain *why* when the reason is not obvious from the diff. -This repository runs the following GitHub Actions on every PR: +## CI -- **Markdown Lint** — line length, formatting rules -- **TypeScript Lint** — type checking for `.ts`/`.tsx` files -- **Deploy to GitHub Pages** — only runs on main branch after merge +`.github/workflows/gh-page.yml`: -All checks must pass before a PR can be merged. +| 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. ## Development Workflow -All contributions follow a fork-based workflow with Git Worktree for parallel -task development. +Fork-based, with git worktrees for parallel tasks. -### Git Setup +### Setup ```bash -# Fork zncdatadev/docs to your personal account -# Clone and configure remotes git clone https://github.com//docs.git +cd docs git remote add upstream https://github.com/zncdatadev/docs.git ``` -### Workflow Steps +### Steps + +1. Sync: `git fetch upstream && git switch main && git merge --ff-only upstream/main` +2. Branch off upstream main — see naming below +3. Optional worktree: `git worktree add ../docs- -b ` +4. Develop, then run `npm run verify` +5. Push to your fork: `git push -u origin ` +6. Open a PR against `zncdatadev/docs` main +7. All CI checks must pass; one reviewer approval is required +8. Clean up after merge: `git worktree remove ` and delete the branch -1. **Sync upstream**: `git pull --rebase upstream main` -2. **Create branch**: use naming convention `/` -3. **Create worktree**: `git worktree add ../docs- -b ` -4. **Develop and verify** in the worktree (run `npm run build`) -5. **Push to fork**: `git push origin ` -6. **Open PR** against `zncdatadev/docs` main branch -7. **Ensure all CI checks pass** (Markdown Lint, TypeScript Lint) -8. **Code Review**: at least 1 reviewer approval required -9. **Clean up** after merge: remove worktree and delete branch +### Do not stack PRs + +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. ### Branch Naming @@ -134,13 +221,7 @@ git remote add upstream https://github.com/zncdatadev/docs.git | Bug fix | `fix/-` | `fix/hdfs-memory-leak` | | Documentation | `docs/` | `docs/add-trino-operator` | | Refactor | `refactor/-` | `refactor/operator-go-api` | -| Dependency | `chore/` | `chore/upgrade-k8s-0.36` | - -### Worktree Conventions - -- Each task gets its own worktree: `docs-` -- Multiple worktrees can run in parallel for the same repo -- Clean up after merge: `git worktree remove ` +| Chore, deps, CI | `chore/` | `chore/upgrade-k8s-0.36` | ### PR Description Template @@ -153,11 +234,13 @@ Brief description of the change. - Change 2 ## Testing -- [ ] `npm run build` passes -- [ ] `npx tsc --noEmit` passes -- [ ] No lines exceeding 200 characters -- [ ] All CI checks pass +- [ ] `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. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 34ca0c7..860f109 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@docusaurus/module-type-aliases": "3.10.1", "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", + "markdownlint-cli2": "0.15.0", "typescript": "~5.8.3" }, "engines": { @@ -5046,6 +5047,19 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@slorber/remark-comment": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", @@ -11324,6 +11338,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", @@ -11451,6 +11472,26 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", + "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/loader-runner": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", @@ -11587,6 +11628,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -11597,6 +11656,133 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdownlint": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.36.1.tgz", + "integrity": "sha512-s73fU2CQN7WCgjhaQUQ8wYESQNzGRNOKDd+3xgVqu8kuTEhmwepd/mxOv1LR2oV046ONrTLBFsM7IoKWNvmy5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.12" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.15.0.tgz", + "integrity": "sha512-4P/lnxQxU2R5lywRJs4b2ajm8z65CW8qqR1bTIcdQ5EG+nZpC6HJlJUnmIR5ee+uecUkoMroazxWcLB7etSmrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "14.0.2", + "js-yaml": "4.1.0", + "jsonc-parser": "3.3.1", + "markdownlint": "0.36.1", + "markdownlint-cli2-formatter-default": "0.0.5", + "micromatch": "4.0.8" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.5.tgz", + "integrity": "sha512-4XKTwQ5m1+Txo2kuQ3Jgpo/KmnG+X90dWt4acufg6HVGadTUG5hzHF/wssp9b5MBYOMCnZ9RMPaU//uHsszF8Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + }, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2/node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/markdownlint-cli2/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.12.tgz", + "integrity": "sha512-RlB6EwMGgc0sxcIhOQ2+aq7Zw1V2fBnzbXKGgYK/mVWdT7cz34fteKSwfYeo4rL6+L/q2tyC9QtD/PgZbkdyJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, "node_modules/marked": { "version": "16.4.2", "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", @@ -12026,6 +12212,13 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "license": "CC0-1.0" }, + "node_modules/mdurl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz", + "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", + "dev": true, + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -16328,6 +16521,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pupa": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", @@ -18472,6 +18675,13 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.19.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", @@ -18527,6 +18737,19 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", diff --git a/package.json b/package.json index 107bbd4..4a0886d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,10 @@ "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" + "typecheck": "tsc", + "lint:md": "markdownlint-cli2 \"*.md\" \"docs/**/*.md\" \"i18n/**/*.md\"", + "lint": "npm run lint:md && npm run typecheck", + "verify": "npm run lint && npm run build" }, "dependencies": { "@docusaurus/core": "3.10.1", @@ -28,6 +31,7 @@ "@docusaurus/module-type-aliases": "3.10.1", "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", + "markdownlint-cli2": "0.15.0", "typescript": "~5.8.3" }, "browserslist": {