This guide covers everything you need to get set up and submit changes.
git clone https://github.com/chris-c-thomas/LexBuild.git
cd LexBuild
pnpm install
pnpm turbo buildVerify everything is working:
pnpm turbo test && pnpm turbo lint && pnpm turbo typecheckpnpm 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 build --filter=@lexbuild/core
pnpm turbo test --filter=@lexbuild/usc
pnpm turbo test --filter=@lexbuild/cliAfter building, run the CLI directly from the dist output:
node packages/cli/dist/index.js download --titles 1
node packages/cli/dist/index.js convert --titles 1-5 -o ./output
node packages/cli/dist/index.js convert ./downloads/usc/xml/usc01.xml -o ./outputpnpm format # Auto-format all files
pnpm format:check # Check formatting without writingFormatting is enforced by Prettier (double quotes, trailing commas, 100 char print width).
packages/
core/ @lexbuild/core — XML parsing, AST, Markdown rendering, shared utilities
usc/ @lexbuild/usc — U.S. Code conversion logic and OLRC downloader
cli/ @lexbuild/cli — CLI entry point (the published npm package)
The core package provides the general-purpose XML-to-Markdown pipeline. The usc package adds U.S. Code-specific handling. The cli package wires everything together as a command-line tool. Internal packages use workspace:* protocol for dependencies.
- Strict mode —
strict: true,noUncheckedIndexedAccess: true,exactOptionalPropertyTypes: 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
| Category | Convention | Example |
|---|---|---|
| Files | kebab-case.ts |
ast-builder.ts |
| Types / Interfaces | PascalCase |
SectionNode, ConvertOptions |
| Functions | camelCase |
parseIdentifier, renderSection |
| Constants | UPPER_SNAKE_CASE |
USLM_NAMESPACE |
- XML parsing errors: warn and continue (don't crash on anomalous structures)
- File I/O errors: throw with context (file path, operation attempted)
- Never swallow errors silently — at minimum, log at
warnlevel
Tests are co-located with source files (parser.ts → parser.test.ts).
pnpm turbo test # Run all tests
pnpm turbo test --filter=@lexbuild/usc # Run one packageName test cases descriptively:
it("converts <subsection> with chapeau to indented bold-lettered paragraph")Output 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 withlexbuild 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.
- Getting Started — Detailed setup and orientation
- Coding Standards — Full TypeScript conventions and naming rules
- Testing — Test framework, fixtures, and snapshot workflow
- Release Process — Changesets, versioning, and publishing pipeline
- Architecture Overview — System design and package layers
By contributing, you agree that your contributions will be licensed under the MIT License.