From 9d96b7876379d8a9029f3c6ea80a6d1ae290c42a Mon Sep 17 00:00:00 2001 From: Ant Somers Date: Fri, 8 May 2026 22:23:19 +0300 Subject: [PATCH 1/2] feat(ci): add website + docs CI workflows for merged docs source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Mintlify docs source merged in 6d1004a had no CI coverage and the website itself had no CI gates. This adds two scoped workflows (website: lint/format:check/build; docs: prettier/markdownlint/mintlify broken-links) plus the tooling to support them, and documents the new boundary in AGENTS.md. - .github/workflows/website.yml — paths-ignore docs/**; pnpm@10/node@24; permissions: contents: read. - .github/workflows/docs.yml — paths docs/** + tool-config + lockfile so devDep bumps re-run; pinned mintlify@4.2.555. - .markdownlint-cli2.jsonc — MDX-friendly (MD013/033/034/041 disabled); markdownlint-cli2 added as devDep. - ESLint globalIgnores docs/**; lint-staged glob now covers .mdx. - AGENTS.md — Layout entry + Gotcha explaining the docs surface is a separate Mintlify build, not part of pnpm build. - Drive-bys: gitignore .claude/settings.local.json (untracked local drift was breaking format:check); reformat the 10 merged MDX files with Prettier; add 'text' language to one fenced block (MD040). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/docs.yml | 42 ++ .github/workflows/website.yml | 32 ++ .gitignore | 3 + .markdownlint-cli2.jsonc | 15 + .prettierignore | 1 + AGENTS.md | 2 + docs/overview/architecture.mdx | 10 +- docs/overview/glossary.mdx | 32 +- docs/overview/how-it-works.mdx | 14 +- docs/overview/participants.mdx | 16 +- docs/protocol/content-addressing.mdx | 12 +- docs/protocol/governance.mdx | 14 +- docs/protocol/privacy.mdx | 12 +- docs/protocol/reputation.mdx | 12 +- docs/protocol/slashing.mdx | 12 +- docs/protocol/takedown.mdx | 12 +- eslint.config.mjs | 2 + package.json | 3 +- pnpm-lock.yaml | 556 +++++++++++++++++++++++++++ 19 files changed, 728 insertions(+), 74 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/website.yml create mode 100644 .markdownlint-cli2.jsonc diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..35c61f5 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,42 @@ +name: docs + +on: + pull_request: + paths: + - "docs/**" + - ".github/workflows/docs.yml" + - ".markdownlint-cli2.jsonc" + - "package.json" + - "pnpm-lock.yaml" + push: + branches: [main] + paths: + - "docs/**" + - ".github/workflows/docs.yml" + - ".markdownlint-cli2.jsonc" + - "package.json" + - "pnpm-lock.yaml" + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - name: Prettier check + run: pnpm exec prettier --check "docs/**/*.{md,mdx,json}" + - name: markdownlint + run: pnpm exec markdownlint-cli2 + - name: Mintlify broken-link check + working-directory: docs + run: npx -y mintlify@4.2.555 broken-links diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 0000000..a8689a4 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,32 @@ +name: website + +on: + pull_request: + paths-ignore: + - "docs/**" + - "**/*.md" + push: + branches: [main] + paths-ignore: + - "docs/**" + - "**/*.md" + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm lint + - run: pnpm format:check + - run: pnpm build diff --git a/.gitignore b/.gitignore index 5ef6a52..796f79c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Claude Code local-only state +.claude/settings.local.json diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..ff26d0b --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,15 @@ +{ + "config": { + "default": true, + // Line length — Mintlify pages mix prose with long inline links. + "MD013": false, + // Inline HTML — MDX components are inline JSX. + "MD033": false, + // Bare URLs — allowed in prose; Mintlify auto-renders them as links. + "MD034": false, + // First-line h1 — Mintlify uses `title:` frontmatter, not an h1. + "MD041": false, + }, + "globs": ["docs/**/*.{md,mdx}"], + "ignores": ["**/node_modules/**", "docs/.mintlify/**"], +} diff --git a/.prettierignore b/.prettierignore index 496cf00..94cb687 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,3 +5,4 @@ node_modules/ pnpm-lock.yaml next-env.d.ts .husky/_/ +.claude/settings.local.json diff --git a/AGENTS.md b/AGENTS.md index 0e23810..25eb53e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,7 @@ pnpm format # prettier --write . - `components/site/` — page sections composed by `app/page.tsx` (Hero, Problem, …). - `components/ui/` — low-level primitives (Button, Section, Stat, Mono). - `lib/` — shared helpers (currently just `links.ts`). +- `docs/` — Mintlify source for `docs.decdn.org` (separate build pipeline, not part of the static export). - Path alias `@/*` → project root (e.g. `@/lib/links`, not `@/src/...`). ## Gotchas @@ -34,3 +35,4 @@ pnpm format # prettier --write . - **Tailwind v4.** `globals.css` uses `@import "tailwindcss"` and `@theme inline { … }`. There is no `tailwind.config.*` — theme tokens live in CSS. Don't reach for v3 directives. - **Conventional commits required.** `commitlint` runs in the `commit-msg` husky hook; non-conforming messages are rejected. - **`metadataBase` is live.** `lib/links.ts` `site` is the real origin and `INDEXABLE` is `true`. Anything anchored on this origin — OG and canonical (via `metadataBase`); JSON-LD, `app/sitemap.ts`, `app/robots.ts` (via `SITE_URL`) — ships to production. Adding a new page = append an entry to `app/sitemap.ts`; don't add config elsewhere. Flip `INDEXABLE` to take the site out of search; only the meta tag flips (see `lib/links.ts` for why `robots.txt` stays unconditional). +- **`docs/` is a different product.** Mintlify Cloud builds it from `docs/docs.json` and serves it at `docs.decdn.org` — independent of `pnpm build`. The website code must not import from `docs/`; ESLint and the website CI workflow ignore it. Edits to MDX go through the `docs` workflow (Prettier + `markdownlint-cli2` + `mintlify broken-links`). diff --git a/docs/overview/architecture.mdx b/docs/overview/architecture.mdx index 9b6090c..00b0a72 100644 --- a/docs/overview/architecture.mdx +++ b/docs/overview/architecture.mdx @@ -39,11 +39,11 @@ graph TD ## Participant roles -| Role | Operated by | Participates in CDN? | -| --- | --- | --- | -| **Node (pure cache)** | Independent node operator | Yes — stakes, gossips, probes, delivers | -| **Node (origin-backed)** | Content provider *or* node operator with storage | Yes — same protocol, plus a private origin backend | -| **Client** | End-user or application | Pays for bytes; subscribes to gossip but does not publish | +| Role | Operated by | Participates in CDN? | +| ------------------------ | ------------------------------------------------ | --------------------------------------------------------- | +| **Node (pure cache)** | Independent node operator | Yes — stakes, gossips, probes, delivers | +| **Node (origin-backed)** | Content provider _or_ node operator with storage | Yes — same protocol, plus a private origin backend | +| **Client** | End-user or application | Pays for bytes; subscribes to gossip but does not publish | See [Participants](/overview/participants) for a deeper breakdown per role. diff --git a/docs/overview/glossary.mdx b/docs/overview/glossary.mdx index dba124c..f69f7c8 100644 --- a/docs/overview/glossary.mdx +++ b/docs/overview/glossary.mdx @@ -3,20 +3,20 @@ title: Glossary description: Core terms used across the deCDN protocol and this documentation. --- -| Term | Definition | -| --- | --- | -| **Blob** | A content-addressed byte sequence. Every blob is identified by its hash; clients verify received bytes against the known hash. | -| **Channel (payment)** | On-chain escrow between client and node that backs off-chain vouchers. Opens with a deposit; settles with the latest voucher. | -| **Client** | A lightweight QUIC endpoint that streams content and pays per MB. No stake, no gossip publish. | -| **DHT** | Kademlia-subset content discovery. Nodes self-publish records when caching a blob. | -| **Gossip** | Epidemic broadcast over topic channels for node metadata and rate updates. | -| **Hash sequence** | An ordered collection of blob hashes (a directory or manifest equivalent). | -| **Node** | A staked QUIC endpoint that caches and delivers blobs. Some are origin-backed; others are pure caches. | +| Term | Definition | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Blob** | A content-addressed byte sequence. Every blob is identified by its hash; clients verify received bytes against the known hash. | +| **Channel (payment)** | On-chain escrow between client and node that backs off-chain vouchers. Opens with a deposit; settles with the latest voucher. | +| **Client** | A lightweight QUIC endpoint that streams content and pays per MB. No stake, no gossip publish. | +| **DHT** | Kademlia-subset content discovery. Nodes self-publish records when caching a blob. | +| **Gossip** | Epidemic broadcast over topic channels for node metadata and rate updates. | +| **Hash sequence** | An ordered collection of blob hashes (a directory or manifest equivalent). | +| **Node** | A staked QUIC endpoint that caches and delivers blobs. Some are origin-backed; others are pure caches. | | **Origin-backed node** | A node configured with an S3-compatible store, NFS mount, or local disk — the canonical source for specific blobs. Never experiences a true cache miss. | -| **Origin backend** | The opaque storage behind an origin-backed node (S3, R2, B2, MinIO, NFS, local disk). Never exposed to the network. | -| **Peer mesh** | The flat set of all staked nodes. Discovery via gossip; content location via DHT. | -| **Probe** | Parallel latency + availability check that runs before any delivery commitment. | -| **Selection score** | A combined ranking over advertised price, observed latency, and reputation. Lower is better. | -| **Stake** | TOKEN locked on-chain by a node to join the mesh. Returned on deregistration after an unbonding period. | -| **TOKEN** | The deCDN governance and staking token. Not used for payments. | -| **Voucher** | A signed off-chain payment message. The primary payment instrument between client and node. | +| **Origin backend** | The opaque storage behind an origin-backed node (S3, R2, B2, MinIO, NFS, local disk). Never exposed to the network. | +| **Peer mesh** | The flat set of all staked nodes. Discovery via gossip; content location via DHT. | +| **Probe** | Parallel latency + availability check that runs before any delivery commitment. | +| **Selection score** | A combined ranking over advertised price, observed latency, and reputation. Lower is better. | +| **Stake** | TOKEN locked on-chain by a node to join the mesh. Returned on deregistration after an unbonding period. | +| **TOKEN** | The deCDN governance and staking token. Not used for payments. | +| **Voucher** | A signed off-chain payment message. The primary payment instrument between client and node. | diff --git a/docs/overview/how-it-works.mdx b/docs/overview/how-it-works.mdx index 95aebf7..e07df07 100644 --- a/docs/overview/how-it-works.mdx +++ b/docs/overview/how-it-works.mdx @@ -64,12 +64,12 @@ If pull-through is disabled in the node's config, the node returns a redirect po ## Where the boundary sits -| Layer | Trust | -| --- | --- | -| Bytes delivered | **Verified** against known hash | -| Node availability | Trusted — slashed if phantom-announced | -| Node rate honesty | Trusted — slashed if advertised rate contradicts charged rate | -| Origin backend correctness | **Assumed** — outside protocol scope (operator concern) | -| L2 RPC provider honesty | **Assumed** — mitigated via multi-source bootstrap | +| Layer | Trust | +| -------------------------- | ------------------------------------------------------------- | +| Bytes delivered | **Verified** against known hash | +| Node availability | Trusted — slashed if phantom-announced | +| Node rate honesty | Trusted — slashed if advertised rate contradicts charged rate | +| Origin backend correctness | **Assumed** — outside protocol scope (operator concern) | +| L2 RPC provider honesty | **Assumed** — mitigated via multi-source bootstrap | See [privacy](/protocol/privacy) for the adversary model. diff --git a/docs/overview/participants.mdx b/docs/overview/participants.mdx index eb45ba0..ea8fd62 100644 --- a/docs/overview/participants.mdx +++ b/docs/overview/participants.mdx @@ -17,9 +17,9 @@ A **node** is a staked QUIC endpoint that caches and serves content-addressed bl Two deployment shapes: -| Shape | What's different | When to run | -| --- | --- | --- | -| **Pure cache** | No origin backend. Pulls missed blobs from other nodes. | You want to earn on popular content; you don't control any origin. | +| Shape | What's different | When to run | +| ----------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| **Pure cache** | No origin backend. Pulls missed blobs from other nodes. | You want to earn on popular content; you don't control any origin. | | **Origin-backed** | Configured with an S3-compatible backend, NFS mount, or local disk. The hash→object-key mapping is a local content catalog. | You are the content provider, or you are running a "last-mile" seed node for a provider. | "Origin-backed" is a deployment choice, not a protocol distinction — the network cannot tell them apart at runtime. @@ -45,8 +45,8 @@ An S3 bucket, R2 bucket, MinIO instance, NFS mount, or local disk. Holds the can ## Who stakes, who pays -| Participant | Stakes? | Pays? | Earns? | -| --- | --- | --- | --- | -| Pure cache node | ✅ TOKEN | ✅ Pays upstream on cache miss | ✅ Per-MB voucher revenue | -| Origin-backed node | ✅ TOKEN | ❌ | ✅ Per-MB voucher revenue | -| Client | ❌ | ✅ Per-MB voucher | ❌ | +| Participant | Stakes? | Pays? | Earns? | +| ------------------ | -------- | ------------------------------ | ------------------------- | +| Pure cache node | ✅ TOKEN | ✅ Pays upstream on cache miss | ✅ Per-MB voucher revenue | +| Origin-backed node | ✅ TOKEN | ❌ | ✅ Per-MB voucher revenue | +| Client | ❌ | ✅ Per-MB voucher | ❌ | diff --git a/docs/protocol/content-addressing.mdx b/docs/protocol/content-addressing.mdx index 8f75755..7b785c2 100644 --- a/docs/protocol/content-addressing.mdx +++ b/docs/protocol/content-addressing.mdx @@ -22,7 +22,7 @@ The on-chain corruption evidence path uses the same chunking ([slashing](/protoc Origin backends speak their own namespace: S3 objects are addressed by key, NFS by path, local disk by filename. Blobs are addressed by BLAKE3 hash. The mapping lives in a **content catalog** — a small database (PostgreSQL or SQLite) maintained by the operator: -``` +```text catalog: hash → { s3_bucket, s3_key, size_bytes, content_type } ``` @@ -36,8 +36,8 @@ This also protects origin operators from direct egress cost attacks: an adversar ## What clients verify vs. trust -| Property | Verified | Trusted | -| --- | --- | --- | -| Byte correctness | BLAKE3 hash tree | — | -| Blob availability | — | Node's signed availability claim (slashable via phantom-announcement path) | -| Origin durability | — | Origin operator's S3/NFS configuration (off-protocol) | +| Property | Verified | Trusted | +| ----------------- | ---------------- | -------------------------------------------------------------------------- | +| Byte correctness | BLAKE3 hash tree | — | +| Blob availability | — | Node's signed availability claim (slashable via phantom-announcement path) | +| Origin durability | — | Origin operator's S3/NFS configuration (off-protocol) | diff --git a/docs/protocol/governance.mdx b/docs/protocol/governance.mdx index b29429f..40eaae7 100644 --- a/docs/protocol/governance.mdx +++ b/docs/protocol/governance.mdx @@ -11,13 +11,13 @@ OpenZeppelin Governor with TOKEN voting, **4% quorum**, and a **2-day timelock** Even governance cannot set parameters outside these bounds: -| Parameter | Bounds | -| --- | --- | -| Slash percentage | 5% – 50% | -| Dispute window | 12 h – 72 h | -| Min stake | > 0 | -| Protocol fee | < 100% | -| Channel close delay | > 0 | +| Parameter | Bounds | +| ------------------- | ----------- | +| Slash percentage | 5% – 50% | +| Dispute window | 12 h – 72 h | +| Min stake | > 0 | +| Protocol fee | < 100% | +| Channel close delay | > 0 | Bounds are enforced in `require()` checks in the setter functions. A malicious governance proposal that attempts to set stake to zero simply reverts. diff --git a/docs/protocol/privacy.mdx b/docs/protocol/privacy.mdx index 5521963..a65c51e 100644 --- a/docs/protocol/privacy.mdx +++ b/docs/protocol/privacy.mdx @@ -9,12 +9,12 @@ Privacy is treated as an **accountability-first** design: probes are public, on- ## Adversary model (four tiers) -| Tier | Example adversary | What they can observe | -| --- | --- | --- | -| **Passive observer** | On-path network middlebox | QUIC metadata (IPs, SNI unless ECH is deployed), timing, volume | -| **Active participant** | Malicious node or client | Probes, gossip activity, payment channel open/close | -| **Infrastructure operator** | L2 RPC provider, relay host | On-chain events at read time; relay endpoints see encrypted QUIC flows | -| **Compromised endpoint** | Malicious origin or content-provider infrastructure | Plaintext bytes, client subscription identity | +| Tier | Example adversary | What they can observe | +| --------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------- | +| **Passive observer** | On-path network middlebox | QUIC metadata (IPs, SNI unless ECH is deployed), timing, volume | +| **Active participant** | Malicious node or client | Probes, gossip activity, payment channel open/close | +| **Infrastructure operator** | L2 RPC provider, relay host | On-chain events at read time; relay endpoints see encrypted QUIC flows | +| **Compromised endpoint** | Malicious origin or content-provider infrastructure | Plaintext bytes, client subscription identity | ## Privacy surfaces diff --git a/docs/protocol/reputation.mdx b/docs/protocol/reputation.mdx index ba0d50c..5e678ca 100644 --- a/docs/protocol/reputation.mdx +++ b/docs/protocol/reputation.mdx @@ -23,12 +23,12 @@ A report's weight is a function of the reporter's track record and counterparty Interaction outcomes generate reports. Examples: -| Event | Local score change | Gossip report? | -| --- | --- | --- | -| Clean delivery, valid voucher accepted | Small positive | Optional | -| Hash mismatch mid-stream | Large negative | Yes | -| Probe claimed availability but stream failed | Negative | Yes (candidate for phantom-announcement slashing) | -| Charged rate ≠ advertised rate | Negative | Yes (candidate for rate-manipulation slashing) | +| Event | Local score change | Gossip report? | +| -------------------------------------------- | ------------------ | ------------------------------------------------- | +| Clean delivery, valid voucher accepted | Small positive | Optional | +| Hash mismatch mid-stream | Large negative | Yes | +| Probe claimed availability but stream failed | Negative | Yes (candidate for phantom-announcement slashing) | +| Charged rate ≠ advertised rate | Negative | Yes (candidate for rate-manipulation slashing) | ## Why not purely on-chain? diff --git a/docs/protocol/slashing.mdx b/docs/protocol/slashing.mdx index 96746d3..4d56536 100644 --- a/docs/protocol/slashing.mdx +++ b/docs/protocol/slashing.mdx @@ -16,12 +16,12 @@ A unified on-chain judge adjudicates all four and triggers stake slashing on res ## Immediate vs. deferred -| Offense | Counter window | Rationale | -| --- | --- | --- | -| Phantom announcement | None — immediate | Probe response + stream failure is self-contained evidence | -| Blacklist violation | None — immediate | Serving a blacklisted hash is self-evident | -| Corrupted delivery | Counter window | The accused can submit a counter-receipt | -| Rate manipulation | Counter window | The accused can submit the legitimate rate change between disputed timestamps | +| Offense | Counter window | Rationale | +| -------------------- | ---------------- | ----------------------------------------------------------------------------- | +| Phantom announcement | None — immediate | Probe response + stream failure is self-contained evidence | +| Blacklist violation | None — immediate | Serving a blacklisted hash is self-evident | +| Corrupted delivery | Counter window | The accused can submit a counter-receipt | +| Rate manipulation | Counter window | The accused can submit the legitimate rate change between disputed timestamps | For high-value disputes the corruption evidence path upgrades to an interactive Merkle proof matching the hash-tree leaf size used for verified streaming ([content addressing](/protocol/content-addressing)). diff --git a/docs/protocol/takedown.mdx b/docs/protocol/takedown.mdx index 9f5e721..074eb4c 100644 --- a/docs/protocol/takedown.mdx +++ b/docs/protocol/takedown.mdx @@ -19,12 +19,12 @@ Gossip-only blacklists fail all three. On-chain entries with governance gating m ## Entry types -| Type | Added by | Active at | Auto-expiry | -| --- | --- | --- | --- | -| Standard governance | Governor | 24 h after vote execution (compliance window) | None (governance can remove) | -| Regional | Regional governance body | 24 h | None | -| Emergency | 3-of-5 multisig | Immediately (with 2 h slash grace) | 14 days | -| Emergency (CSAM / terrorist) | 3-of-5 multisig | Immediately | 90 days | +| Type | Added by | Active at | Auto-expiry | +| ---------------------------- | ------------------------ | --------------------------------------------- | ---------------------------- | +| Standard governance | Governor | 24 h after vote execution (compliance window) | None (governance can remove) | +| Regional | Regional governance body | 24 h | None | +| Emergency | 3-of-5 multisig | Immediately (with 2 h slash grace) | 14 days | +| Emergency (CSAM / terrorist) | 3-of-5 multisig | Immediately | 90 days | Emergency entries **auto-expire unless ratified by governance** before the deadline — preventing the multisig from maintaining a permanent de-facto blacklist without oversight. diff --git a/eslint.config.mjs b/eslint.config.mjs index 2deced1..053c2de 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -13,6 +13,8 @@ const eslintConfig = defineConfig([ "out/**", "build/**", "next-env.d.ts", + // Mintlify docs source: not part of the website build. + "docs/**", ]), prettier, ]); diff --git a/package.json b/package.json index cad75a3..e75258d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "eslint --fix", "prettier --write" ], - "*.{json,md,css,yaml,yml}": [ + "*.{json,md,mdx,css,yaml,yml}": [ "prettier --write" ] }, @@ -43,6 +43,7 @@ "eslint-config-prettier": "^10.1.8", "husky": "^9.1.7", "lint-staged": "^16.4.0", + "markdownlint-cli2": "^0.22.1", "prettier": "^3.8.3", "tailwindcss": "^4", "typescript": "^6" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0938893..bd5230f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,9 @@ importers: lint-staged: specifier: ^16.4.0 version: 16.4.0 + markdownlint-cli2: + specifier: ^0.22.1 + version: 0.22.1 prettier: specifier: ^3.8.3 version: 3.8.3 @@ -308,89 +311,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -457,24 +476,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@16.2.4': resolution: {integrity: sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@16.2.4': resolution: {integrity: sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@16.2.4': resolution: {integrity: sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@16.2.4': resolution: {integrity: sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==} @@ -515,6 +538,10 @@ packages: resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} engines: {node: '>=18'} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -556,24 +583,28 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.2.4': resolution: {integrity: sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.2.4': resolution: {integrity: sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.2.4': resolution: {integrity: sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.2.4': resolution: {integrity: sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==} @@ -609,6 +640,9 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -618,6 +652,12 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@25.6.0': resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} @@ -629,6 +669,9 @@ packages: '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@typescript-eslint/eslint-plugin@8.58.2': resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -727,41 +770,49 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -931,6 +982,15 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} @@ -960,6 +1020,10 @@ packages: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} @@ -1038,6 +1102,9 @@ packages: supports-color: optional: true + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1049,10 +1116,17 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -1081,6 +1155,10 @@ packages: resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -1271,6 +1349,10 @@ packages: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -1385,6 +1467,10 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + globby@16.2.0: + resolution: {integrity: sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==} + engines: {node: '>=20'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -1457,6 +1543,12 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -1495,6 +1587,9 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1519,6 +1614,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -1539,6 +1637,10 @@ packages: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -1629,10 +1731,21 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + katex@0.16.45: + resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1682,24 +1795,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} @@ -1720,6 +1837,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lint-staged@16.4.0: resolution: {integrity: sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==} engines: {node: '>=20.17'} @@ -1750,10 +1870,31 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + + markdownlint-cli2-formatter-default@0.0.6: + resolution: {integrity: sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==} + peerDependencies: + markdownlint-cli2: '>=0.0.4' + + markdownlint-cli2@0.22.1: + resolution: {integrity: sha512-X14ZbytybDCXAViDmtN4DKLt9ZTrRn+oOrxTYlg3a65jS6QcYYbAkGPh/En2L/GDNbFYJ6lKaQSUNrrbN1bPrw==} + engines: {node: '>=20'} + hasBin: true + + markdownlint@0.40.0: + resolution: {integrity: sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==} + engines: {node: '>=20'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} @@ -1762,6 +1903,81 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@4.0.0: + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -1885,6 +2101,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -1935,6 +2154,10 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2068,6 +2291,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + slice-ansi@7.1.2: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} @@ -2076,6 +2303,10 @@ packages: resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} engines: {node: '>=20'} + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2099,6 +2330,10 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string-width@8.1.0: + resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==} + engines: {node: '>=20'} + string-width@8.2.1: resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} engines: {node: '>=20'} @@ -2233,6 +2468,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -2240,6 +2478,10 @@ packages: undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} @@ -2788,6 +3030,8 @@ snapshots: '@simple-libs/stream-utils@1.2.0': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -2866,12 +3110,20 @@ snapshots: tslib: 2.8.1 optional: true + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/katex@0.16.8': {} + + '@types/ms@2.1.0': {} + '@types/node@25.6.0': dependencies: undici-types: 7.19.2 @@ -2884,6 +3136,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/unist@2.0.11': {} + '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -3206,6 +3460,12 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 @@ -3233,6 +3493,8 @@ snapshots: commander@14.0.3: {} + commander@8.3.0: {} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 @@ -3307,6 +3569,10 @@ snapshots: dependencies: ms: 2.1.3 + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + deep-is@0.1.4: {} define-data-property@1.1.4: @@ -3321,8 +3587,14 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + dequal@2.0.3: {} + detect-libc@2.1.2: {} + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -3350,6 +3622,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.3 + entities@4.5.0: {} + env-paths@2.2.1: {} environment@1.1.0: {} @@ -3686,6 +3960,14 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -3802,6 +4084,15 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 + globby@16.2.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -3857,6 +4148,13 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.9 @@ -3903,6 +4201,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -3927,6 +4227,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-map@2.0.3: {} is-negative-zero@2.0.3: {} @@ -3940,6 +4242,8 @@ snapshots: is-obj@2.0.0: {} + is-path-inside@4.0.0: {} + is-plain-obj@4.1.0: {} is-regex@1.2.1: @@ -4020,6 +4324,10 @@ snapshots: json5@2.2.3: {} + jsonc-parser@3.3.1: {} + + jsonpointer@5.0.1: {} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.9 @@ -4027,6 +4335,10 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + katex@0.16.45: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -4093,6 +4405,10 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + lint-staged@16.4.0: dependencies: commander: 14.0.3 @@ -4137,12 +4453,227 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdownlint-cli2-formatter-default@0.0.6(markdownlint-cli2@0.22.1): + dependencies: + markdownlint-cli2: 0.22.1 + + markdownlint-cli2@0.22.1: + dependencies: + globby: 16.2.0 + js-yaml: 4.1.1 + jsonc-parser: 3.3.1 + jsonpointer: 5.0.1 + markdown-it: 14.1.1 + markdownlint: 0.40.0 + markdownlint-cli2-formatter-default: 0.0.6(markdownlint-cli2@0.22.1) + micromatch: 4.0.8 + smol-toml: 1.6.1 + transitivePeerDependencies: + - supports-color + + markdownlint@0.40.0: + dependencies: + micromark: 4.0.2 + micromark-core-commonmark: 2.0.3 + micromark-extension-directive: 4.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-math: 3.1.0 + micromark-util-types: 2.0.2 + string-width: 8.1.0 + transitivePeerDependencies: + - supports-color + math-intrinsics@1.1.0: {} + mdurl@2.0.0: {} + meow@13.2.0: {} merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@4.0.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.45 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4276,6 +4807,16 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.29.0 @@ -4319,6 +4860,8 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + punycode.js@2.3.1: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -4499,6 +5042,8 @@ snapshots: signal-exit@4.1.0: {} + slash@5.1.0: {} + slice-ansi@7.1.2: dependencies: ansi-styles: 6.2.3 @@ -4509,6 +5054,8 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + smol-toml@1.6.1: {} + source-map-js@1.2.1: {} stable-hash@0.0.5: {} @@ -4532,6 +5079,11 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 + string-width@8.1.0: + dependencies: + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + string-width@8.2.1: dependencies: get-east-asian-width: 1.5.0 @@ -4694,6 +5246,8 @@ snapshots: typescript@6.0.3: {} + uc.micro@2.1.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -4703,6 +5257,8 @@ snapshots: undici-types@7.19.2: {} + unicorn-magic@0.4.0: {} + unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 From fac56d6279ff752b929b3810f587f6b8b0dff372 Mon Sep 17 00:00:00 2001 From: Ant Somers Date: Fri, 8 May 2026 22:45:35 +0300 Subject: [PATCH 2/2] fix(ci): tighten path filters and lint-staged scope - website.yml: drop `**/*.md` from paths-ignore so root-MD-only PRs (AGENTS.md, README.md, CLAUDE.md) still run `pnpm format:check`. - docs.yml: add `.prettierrc.json` and `.prettierignore` to both triggers so changes to Prettier config re-run the docs check. - package.json: add `markdownlint-cli2 --fix` to the lint-staged glob for `docs/**/*.{md,mdx}`, matching the CI scope so commit-time enforcement mirrors what CI catches. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/docs.yml | 4 ++++ .github/workflows/website.yml | 2 -- package.json | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 35c61f5..d58055b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,6 +6,8 @@ on: - "docs/**" - ".github/workflows/docs.yml" - ".markdownlint-cli2.jsonc" + - ".prettierrc.json" + - ".prettierignore" - "package.json" - "pnpm-lock.yaml" push: @@ -14,6 +16,8 @@ on: - "docs/**" - ".github/workflows/docs.yml" - ".markdownlint-cli2.jsonc" + - ".prettierrc.json" + - ".prettierignore" - "package.json" - "pnpm-lock.yaml" diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index a8689a4..6962426 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -4,12 +4,10 @@ on: pull_request: paths-ignore: - "docs/**" - - "**/*.md" push: branches: [main] paths-ignore: - "docs/**" - - "**/*.md" permissions: contents: read diff --git a/package.json b/package.json index e75258d..72b812a 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,9 @@ "eslint --fix", "prettier --write" ], + "docs/**/*.{md,mdx}": [ + "markdownlint-cli2 --fix" + ], "*.{json,md,mdx,css,yaml,yml}": [ "prettier --write" ]