From 78da18d1c27ba34499b87ed6f5f9378cc36fe77c Mon Sep 17 00:00:00 2001 From: Jocs Date: Thu, 21 May 2026 09:20:34 +0800 Subject: [PATCH 1/2] docs: align CONTRIBUTING.md with pnpm/Turborepo stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial CONTRIBUTING.md added in #193 documented npm + a `main` branch + a generic style guide, none of which match the repo's actual conventions. New contributors following it would fail on the first `npm install`, then again at the commitlint hook. This rewrite covers what's actually enforced today: - pnpm 10.22 + Turborepo, Node engines (≥18 for dev, ≥20.19/≥22.13/≥24 for release). - `master` as the base branch. - Conventional Commits enforced by husky + commitlint, with the allowed type list and example subjects. - antfu ESLint rules that actually flag PRs: `I`-prefixed interfaces, `_`-prefixed private members, 4-space indent, complexity caps, the `pnpm check-circular` gate. - Real command surface: `pnpm dev/build/test/coverage/lint/lint:types/ lint:css/check-circular/e2e/e2e:ui` and the scoped `--filter @muyajs/core test:spec[:commonmark|:gfm]` runs. - Repository layout (packages/core as the only source package today, examples/, e2e/, stub packages), with a pointer to CLAUDE.md for architecture. - A "before opening a PR" checklist that mirrors what reviewers ask for in practice (lint, types, tests, check-circular, e2e/spec when relevant, MIGRATION.md updates for public-API changes). - Issues-only support routing (Discussions are not enabled on this repo). Refs #193. --- CONTRIBUTING.md | 211 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 151 insertions(+), 60 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 204d08bf..3865b310 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,88 +1,179 @@ -Contributing to Muya ---- +# Contributing to Muya -First, thank you for considering a contribution to Muya! It's people like you that make Muya a -better tool for everyone. +Thanks for your interest in improving Muya! This document covers everything you need to file a useful issue or land a pull request against `@muyajs/core`. -Muya is a web-based Markdown editor engine, originally part of * -*[MarkText](https://github.com/marktext/marktext)**. We are excited to have you help us improve its -performance, stability, and feature set. +Muya is a web-based Markdown editor engine extracted from [MarkText](https://github.com/marktext/marktext). The bulk of the source today lives in `packages/core/`. -# Table of Contents +## Table of contents -* Code of Conduct -* How Can I Contribute? -* Development Setup -* Pull Request Process -* Style Guide +- [Code of conduct](#code-of-conduct) +- [Ways to contribute](#ways-to-contribute) +- [Development setup](#development-setup) +- [Repository layout](#repository-layout) +- [Useful commands](#useful-commands) +- [Coding conventions](#coding-conventions) +- [Commits and pull requests](#commits-and-pull-requests) +- [Testing](#testing) +- [Where to ask questions](#where-to-ask-questions) -# Code of Conduct +## Code of conduct -By participating in this project, you agree to abide by our code of conduct. We expect all -contributors to be kind, treat each other with respect, and forgive mistakes. +Be kind, assume good intent, and keep discussions on-topic. Personal attacks, harassment, and discriminatory language are not welcome. Reports about violations can be sent to the maintainers via a GitHub DM or by opening a confidential issue. -# How Can I Contribute? +## Ways to contribute -# Reporting Bugs +- **Report a bug** — open an issue with a clear title, a minimal reproduction (Markdown input + steps), and the muya / browser version. Search [existing issues](https://github.com/marktext/muya/issues) first to avoid duplicates. +- **Suggest an enhancement** — open an issue tagged with `enhancement` and explain the use case. Larger proposals (new public API, new block type) benefit from a short design sketch before the PR. +- **Improve docs** — README, `CLAUDE.md`, `MIGRATION.md`, `docs/`, and the per-package READMEs are all fair game. +- **Send a pull request** — bug fixes, parser conformance improvements, new UI plugins, performance wins, tests, and CI hardening are all appreciated. See [Commits and pull requests](#commits-and-pull-requests) below. -* Check the Issue Tracker to ensure the bug hasn't already been reported. -* If you find a new bug, please open a new issue. Include a clear title, a description of the - problem, and steps to reproduce the bug. +## Development setup -# Suggesting Enhancements +**Prerequisites** -* We welcome feature requests! Please open an issue and label it as an `enhancement`. -* Provide as much context as possible about why the feature would be useful. +- Node.js ≥18 for everyday development. **Releases require Node ≥20.19, ≥22.13, or ≥24** (the changelog plugin pins `^20.19.0 || ^22.13.0 || >=24.0.0`). +- [pnpm](https://pnpm.io/) ≥8.5. The repo is pinned to `pnpm@10.22.0` via `packageManager` — install the matching version (e.g. `corepack enable && corepack prepare pnpm@10.22.0 --activate`). +- A Chromium-based browser for the dev demo and Playwright E2E suite. -# Improving Documentation +**First-time setup** -* Documentation is vital for Muya's success. Whether it's fixing a typo or writing new guides, your - help is valued. +```sh +# 1. Fork on GitHub, then clone your fork. +git clone git@github.com:/muya.git +cd muya -# Development Setup +# 2. Add the upstream remote so you can keep master in sync. +git remote add upstream git@github.com:marktext/muya.git -To start developing on Muya, follow these steps: +# 3. Install dependencies (also wires up husky git hooks). +pnpm install -1. **Fork the repository** to your own GitHub account. -2. **Clone the fork** to your local machine: +# 4. Boot the examples app to try your changes in a real editor. +pnpm dev +``` - ```bash - git clone [your-fork-repo-url] - ``` +`pnpm dev` runs `turbo dev:demo`, which starts the Vite dev server in `examples/` and serves `@muyajs/core` directly from `packages/core/src/` — no rebuild step needed while iterating. -3. **Install dependencies**: +## Repository layout - ```bash - npm install - - ``` +``` +. +├── packages/ +│ ├── core/ @muyajs/core — the editor library (all source today) +│ ├── facade/ README-only stub (no source yet) +│ └── findReplace/ README-only stub (no source yet) +├── examples/ Vite vanilla-TS demo, consumes core via workspace:* +├── e2e/ Playwright real-browser suite (self-contained host page) +├── docs/ Logo, ROADMAP, JSON state reference +├── CLAUDE.md Architecture + conventions deep-dive (start here for big changes) +└── CHANGELOG.md Generated by release-it (angular conventional-changelog preset) +``` + +`CLAUDE.md` documents the runtime architecture (Muya → Editor → JSONState, the block tree, plugin registration, state ↔ markdown round-trip) and is the fastest way to orient yourself before touching `packages/core/src/`. + +## Useful commands + +Run from the repo root — Turbo fans tasks out across packages. + +| Command | What it does | +| --- | --- | +| `pnpm dev` | Boot the examples Vite dev server (`turbo dev:demo`). | +| `pnpm build` | `tsc && vite build` in `packages/core`. Emits `lib/{es,umd,cjs}` and `lib/types`. | +| `pnpm test` | Vitest unit tests (`--passWithNoTests`). | +| `pnpm coverage` | Vitest with V8 coverage. | +| `pnpm lint` / `pnpm lint:fix` | ESLint (antfu base) over `packages/`. | +| `pnpm lint:types` | `tsc --noEmit` per package. | +| `pnpm lint:css` | Stylelint over all CSS. | +| `pnpm check-circular` | `madge --circular packages/core/src/index.ts` — CI enforces this. | +| `pnpm e2e` | Playwright suite (Chromium, port 5174). See `e2e/README.md`. | +| `pnpm e2e:ui` | Playwright UI mode for interactive debugging. | + +Scoped runs: + +```sh +# Run one Vitest file in core. +pnpm --filter @muyajs/core exec vitest run path/to/file.test.ts + +# Watch a single package while iterating. +pnpm --filter @muyajs/core test:watch + +# Run only the CommonMark / GFM conformance fixtures (baseline locked by +# packages/core/test/spec/expected-failures.json). +pnpm --filter @muyajs/core test:spec:commonmark +pnpm --filter @muyajs/core test:spec:gfm +``` + +## Coding conventions + +ESLint and Stylelint enforce most of these — `pnpm lint:fix` is the source of truth — but a few are worth knowing up front: -4. **Run the project locally**: +- **TypeScript first.** All new source goes in `.ts`. Public types belong in `packages/core/src/types.ts`. +- **4-space indent, semicolons required.** The antfu config in `eslint.config.mjs` configures this for the repo. +- **Interface names start with `I`** followed by an uppercase letter or digit (e.g. `IMuyaOptions`, `IPlugin`). The `@typescript-eslint/naming-convention` rule flags violations. +- **Private class members are prefixed with `_`** (e.g. `_uiPlugins`, `_activeContentBlock`). +- **Complexity caps.** `complexity ≤ 20` and `max-lines-per-function ≤ 200` are warnings for non-test TS. Refactor rather than disable. +- **No circular imports.** `pnpm check-circular` runs in CI; adding a cycle into `packages/core/src/index.ts` fails the build. +- **Block registration.** New block types must be registered in `packages/core/src/block/index.ts::registerBlocks()`. `ScrollPage.loadBlock(name)` returns `undefined` and warns otherwise. +- **No new code paths producing `ILinkReferenceDefinitionState`.** Reference link/image definitions round-trip through paragraph state — see `markdownToState.ts` and `CLAUDE.md`. +- **Avoid backwards-compat shims** (renaming unused vars to `_var`, leaving "removed" comments, re-exporting deleted types). Delete unused code outright. - ```bash - npm run dev - +CSS lives next to its consumer (`*.css` co-located with the `.ts`) and is linted with Stylelint. + +## Commits and pull requests + +**Conventional Commits are required.** The husky `commit-msg` hook runs commitlint and rejects subjects that don't match. Allowed types: + +``` +build, ci, chore, docs, feat, fix, perf, refactor, revert, style, test +``` + +Examples: + +``` +feat(core): add reference-image rendering +fix(inline): preserve cursor after IME composition +docs: clarify Muya.use registration order +test(spec): widen GFM table fixture coverage +``` + +Scope is optional but encouraged for `packages/core/` work (`core`, `inline`, `state`, `ui`, `spec`, …). + +**Before opening a PR** + +1. Branch off `master`: `git checkout -b fix/short-description`. +2. Make focused commits — bundle drive-by cleanups into separate commits or PRs. +3. Run the quality gates locally: + + ```sh + pnpm lint + pnpm lint:types + pnpm test + pnpm check-circular ``` -# Pull Request Process +4. If your change touches the UI or editing surface, run `pnpm e2e` and add coverage for the new behavior under `e2e/tests/`. +5. If your change affects markdown parsing or HTML output, check the conformance baseline doesn't regress: `pnpm --filter @muyajs/core test:spec`. Conformance can only go up — see `packages/core/test/spec/expected-failures.json`. +6. Update `MIGRATION.md` if you change a public API. + +**Opening the PR** + +- Base branch is `master` (not `main`). +- Use a Conventional-Commit-style title (it becomes the squash commit subject). +- Describe the **why** in the body, not just the **what** — the diff already shows the what. Link related issues with `Closes #123` / `Refs #123`. +- Pre-commit, `lint-staged` runs `eslint --fix` on staged `*.ts` and `stylelint --fix` on staged `*.{html,css}`. If a hook fails, fix the issue and create a new commit — **don't bypass with `--no-verify`** unless a maintainer asks you to. + +Maintainers will review and may ask for changes. PRs are merged via **squash merge** to keep `master` linear; your branch commits don't need to be individually clean. -1. **Create a new branch** for your changes: `git checkout -b feature/your-feature-name`. -2. **Make your changes** and ensure they follow the Style Guide. -3. **Run tests** to ensure no regressions: `npm test`. -4. **Commit your changes** with descriptive messages. -5. **Push to your fork** and open a Pull Request against the `main` branch. -6. Wait for a maintainer to review your PR. Be prepared to make requested changes. +## Testing -# Style Guide +- **Unit tests** live next to their source in `packages/core/src/**/__tests__/` or `*.test.ts`, run with Vitest under `happy-dom`. New parser logic, state transforms, and pure helpers should ship with unit coverage. +- **Conformance fixtures.** `pnpm --filter @muyajs/core test:spec` runs the CommonMark 0.31 and GFM 0.29-gfm fixture suites against `renderToStaticHTML(..., { sanitize: false })`. The expected-failures list is locked — making a failing fixture pass requires removing it from the list in the same PR. +- **E2E tests.** Playwright suite in `e2e/`. Real browser, real contenteditable. Use this for behaviors that depend on selection, IME, clipboard, or floating UI positioning — anything `happy-dom` can't fake. See `e2e/README.md` for the helper API and `e2e/BACKLOG.md` for what's still uncovered. -* **JavaScript**: Follow standard linting rules provided in the project. -* **Markdown**: Muya is a Markdown editor; ensure any documentation follows clear, standard Markdown - formatting. +## Where to ask questions ---- +- **Usage or bug reports** → open an [issue](https://github.com/marktext/muya/issues). Search first; tag with `enhancement` if it's a feature request. +- **Architecture deep-dives** → `CLAUDE.md` is the canonical agent/human-readable map of the codebase. +- **Release tooling** → `README.md` (Publishing section) and `.release-it.json`. -# Useful Links -- [Muya Repository](https://github.com/marktext/muya) -- MarkText Website -- [GitHub Documentation on Contributing](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-open-source) - \ No newline at end of file +Thanks again for contributing — every typo fix, parser improvement, and test counts. From 90b4a88bf80dc5bbbb875bb0cffc5bb887e9cfca Mon Sep 17 00:00:00 2001 From: Jocs Date: Thu, 21 May 2026 09:26:09 +0800 Subject: [PATCH 2/2] docs: address Copilot review on CONTRIBUTING.md Four factual corrections flagged in the PR #236 review: - Code of Conduct: GitHub doesn't have DMs and issues in a public repo aren't confidential. Point at GitHub's abuse-reporting flow and the `author` email in `package.json` instead. - `pnpm coverage`: the configured provider in `packages/core/vite.config.ts` is `istanbul` (`@vitest/coverage-istanbul`), not V8. - lint-staged: `.lintstagedrc` only targets `*.css`, not `*.{html,css}`. - Vitest environment: `vite.config.ts` doesn't set a global `environment`. Tests default to Node and opt into happy-dom with a `// @vitest-environment happy-dom` directive per file. --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3865b310..9004eb58 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Muya is a web-based Markdown editor engine extracted from [MarkText](https://git ## Code of conduct -Be kind, assume good intent, and keep discussions on-topic. Personal attacks, harassment, and discriminatory language are not welcome. Reports about violations can be sent to the maintainers via a GitHub DM or by opening a confidential issue. +Be kind, assume good intent, and keep discussions on-topic. Personal attacks, harassment, and discriminatory language are not welcome. If you witness or experience a violation, you can report it through [GitHub's abuse reporting flow](https://github.com/contact/report-abuse) or by emailing the maintainer listed under `author` in [`package.json`](./package.json). ## Ways to contribute @@ -80,7 +80,7 @@ Run from the repo root — Turbo fans tasks out across packages. | `pnpm dev` | Boot the examples Vite dev server (`turbo dev:demo`). | | `pnpm build` | `tsc && vite build` in `packages/core`. Emits `lib/{es,umd,cjs}` and `lib/types`. | | `pnpm test` | Vitest unit tests (`--passWithNoTests`). | -| `pnpm coverage` | Vitest with V8 coverage. | +| `pnpm coverage` | Vitest with Istanbul coverage (`@vitest/coverage-istanbul`). | | `pnpm lint` / `pnpm lint:fix` | ESLint (antfu base) over `packages/`. | | `pnpm lint:types` | `tsc --noEmit` per package. | | `pnpm lint:css` | Stylelint over all CSS. | @@ -160,13 +160,13 @@ Scope is optional but encouraged for `packages/core/` work (`core`, `inline`, `s - Base branch is `master` (not `main`). - Use a Conventional-Commit-style title (it becomes the squash commit subject). - Describe the **why** in the body, not just the **what** — the diff already shows the what. Link related issues with `Closes #123` / `Refs #123`. -- Pre-commit, `lint-staged` runs `eslint --fix` on staged `*.ts` and `stylelint --fix` on staged `*.{html,css}`. If a hook fails, fix the issue and create a new commit — **don't bypass with `--no-verify`** unless a maintainer asks you to. +- Pre-commit, `lint-staged` runs `eslint --fix` on staged `*.ts` and `stylelint --fix` on staged `*.css` (see `.lintstagedrc`). If a hook fails, fix the issue and create a new commit — **don't bypass with `--no-verify`** unless a maintainer asks you to. Maintainers will review and may ask for changes. PRs are merged via **squash merge** to keep `master` linear; your branch commits don't need to be individually clean. ## Testing -- **Unit tests** live next to their source in `packages/core/src/**/__tests__/` or `*.test.ts`, run with Vitest under `happy-dom`. New parser logic, state transforms, and pure helpers should ship with unit coverage. +- **Unit tests** live next to their source in `packages/core/src/**/__tests__/` or `*.test.ts`, run with Vitest. Vitest has no global `environment` set — tests run under the default Node environment by default, and DOM-dependent tests opt into happy-dom with a `// @vitest-environment happy-dom` directive at the top of the file. New parser logic, state transforms, and pure helpers should ship with unit coverage. - **Conformance fixtures.** `pnpm --filter @muyajs/core test:spec` runs the CommonMark 0.31 and GFM 0.29-gfm fixture suites against `renderToStaticHTML(..., { sanitize: false })`. The expected-failures list is locked — making a failing fixture pass requires removing it from the list in the same PR. - **E2E tests.** Playwright suite in `e2e/`. Real browser, real contenteditable. Use this for behaviors that depend on selection, IME, clipboard, or floating UI positioning — anything `happy-dom` can't fake. See `e2e/README.md` for the helper API and `e2e/BACKLOG.md` for what's still uncovered.