UMT uses pnpm 11 (the version is pinned in package.json). It installs only versions published more than a day ago and runs install scripts only for the packages approved in pnpm-workspace.yaml (esbuild).
pnpm install
pnpm run typecheck # tsc --noEmit, lib/ and tests/
pnpm run lint # ESLint
pnpm run docs:check # fails on an exported symbol without documentation
pnpm run test:unit # vitest
pnpm run build # dist/umt.js (IIFE), dist/umt.mjs (ESM), dist/umt.d.ts (types)
pnpm dlx http-server . -p 8080 # the demo, index.html
CI runs all of these on every push and pull request, and fails if dist/ does not match the sources.
lib/music-theory/, TypeScript, no runtime dependencies. Library strings are in English; names in other languages go through chord-names.ts.TuningSystem. Do not assume 12-TET: map formulas with tuning.getStepFromStandard(). A function that only makes sense in 12-TET says so in its documentation and returns its "nothing found" value for other tunings.pnpm run docs:check enforces it.@category, the module's group in the Modules section of README.md (Core, Tonal harmony, Post-tonal, World music, Rhythm, Microtonal / Xenharmonic, Notation). It places the export in the API docs menu; without it the export falls under Guides.tests/unit/, headed by the theory sources the module follows. tuning-conformance.test.ts runs every analysis in other tunings against its 12-TET answer: a new function that names or analyses goes into its battery. Reference data (scales, ragas, maqamat, Forte classes, rhythmic cycles) is checked against a cited source, and the source is named in the module.CHANGELOG.md.dist/dist/umt.js, dist/umt.mjs and dist/umt.d.ts are tracked: jsDelivr and GitHub installs serve them. Run pnpm run build and commit them with the source change.
pnpm version X.Y.Z --no-git-tag-version on a clean tree, or set "version" in package.json by hand.CHANGELOG.md entry, and update the version in README.md, GUIDE.md and index.html.pnpm run docs, and commit api-docs/.vX.Y.Z and push the tag with the branch.