Thanks for your interest in contributing to law2md! This guide covers the basics for getting set up and submitting changes.
git clone https://github.com/chris-c-thomas/law2md.git
cd law2md
pnpm install
pnpm turbo buildpnpm turbo build # Build all packages
pnpm turbo test # Run all tests
pnpm turbo lint # Lint all packages
pnpm turbo typecheck # Type-check all packages
pnpm turbo dev # Watch mode (rebuild on change)To scope commands to a single package:
pnpm turbo test --filter=@law2md/core
pnpm turbo test --filter=@law2md/usc
pnpm turbo test --filter=law2mdnode packages/cli/dist/index.js convert path/to/usc01.xml -o ./output
node packages/cli/dist/index.js download --titles 1 # saves to ./downloads/usc/xml/
node packages/cli/dist/index.js convert --titles 1-5 # convert multiple titlespnpm format # Auto-format all files
pnpm format:check # Check formatting without writingpackages/
core/ @law2md/core — XML parsing, AST, Markdown rendering, shared utilities
usc/ @law2md/usc — U.S. Code conversion logic and OLRC downloader
cli/ law2md — CLI entry point (the published npm package)
The core package provides the general-purpose pipeline. The usc package adds U.S. Code-specific handling. The cli package wires everything together as a command-line tool.
- TypeScript strict mode —
strict: true,noUncheckedIndexedAccess: true - ESM only — all packages use
"type": "module" import typefor type-only importsinterfaceovertypefor object shapesunknownoverany— ifanyis truly needed, add an eslint-disable comment with justification- Files:
kebab-case.ts - Types/Interfaces:
PascalCase - Functions:
camelCase - Constants:
UPPER_SNAKE_CASE
See CLAUDE.md for the full conventions reference, USLM schema details, and design decisions.
Tests are co-located with source files (parser.ts → parser.test.ts).
pnpm turbo test # Run all tests
pnpm turbo test --filter=@law2md/usc # Run one packageOutput stability is protected by snapshot tests in packages/usc/src/snapshot.test.ts. Expected output files live in fixtures/expected/.
If you intentionally change rendering output:
cd packages/usc && pnpm exec vitest run --updateReview the diff in fixtures/expected/ to confirm only intended changes, then commit the updated snapshots.
fixtures/fragments/— Small synthetic XML snippets for unit tests (committed)fixtures/expected/— Pinned expected output for snapshot tests (committed)downloads/usc/xml/— Full USC XML files (gitignored, download withlaw2md download)
- Fork the repository and create a feature branch from
main - Make your changes
- Ensure all checks pass:
pnpm turbo build && pnpm turbo test && pnpm turbo lint && pnpm turbo typecheck - Write descriptive commit messages using conventional commits (e.g.,
feat(core):,fix(usc):,docs:) - Open a pull request against
main
- Tests pass (
pnpm turbo test) - Lint clean (
pnpm turbo lint) - Type-check clean (
pnpm turbo typecheck) - New features include tests
- Snapshot updates are intentional and reviewed
- Commit messages follow conventional commit format
This project uses changesets for versioning. If your change affects published package behavior:
pnpm changesetFollow the prompts to describe your change and select the appropriate version bump (patch, minor, major). The changeset file will be committed with your PR and consumed during the next release.
By contributing, you agree that your contributions will be licensed under the MIT License.