Contributing to MailCraft

Thanks for contributing. This guide covers the day-to-day workflow for this repository. See README.md for environment setup and the host-facing API.

Branch model

main is the only long-lived branch and holds production-ready code. There is no integration branch.

Work on a short-lived branch cut from main, named for the change (fix/import-stray-table, feat/storage-provider), and open a pull request back into main. Delete the branch once it merges. Do not commit directly to main, do not force-push it, and do not rewrite published history.

Commit conventions

Match the style already in the log. Most commits use Conventional Commits (type(scope): subject); a plain imperative subject is also fine for straightforward changes. Keep the subject concise and explain the what and the why in the body when it is not obvious.

Reporting a security issue

Do not open a public issue for a suspected vulnerability. Follow the private disclosure process in SECURITY.md.

Repository layout

Build and tests

After any change under src/, rebuild — the demo page loads dist/mailcraft-editor.bundle.js, so a change is not visible until then:

node build.js
npm test

The suites stub localStorage and run against src/ directly; no DOM and no dependencies. The HTML importer has no automated coverage — verify importer changes by hand through the Code modal or a headless Chrome --dump-dom page.

Bundler constraints

build.js is a deliberate regex-transform bundler. It only understands:

No export default, no bare export { ... }, no multi-line imports, no dynamic import(). A new file using anything else fails the build with “unhandled export syntax”.

Conventions

Follow the conventions the code already uses:

Backward-compatible changes

Documents persist in users’ localStorage and templates are stored host-side, both possibly written by older builds: