# Contributing to RoleCraft Thanks for your interest in contributing! Here's how you can help. ## Quick Start ```bash git clone https://github.com/rolecraft-sh/rolecraft.git cd rolecraft npm install # also installs the pre-commit hook automatically npm link # now `rolecraft` runs from your local checkout npm test # full suite, 0 fails expected ``` **Requirements:** Node.js >= 22. Dev dependencies (Biome, VitePress) install locally but never ship to users — the runtime stays zero-dependency. ## Git Hooks A `pre-commit` hook runs `npm run lint` before every commit and rejects the commit on lint errors. It is set up **automatically** by `npm install` via the `postinstall` script — no manual `setup-hooks` step is required. To reinstall or repair the hook manually: ```bash npm run setup-hooks ``` To bypass the hook once (e.g. for a work-in-progress commit), use `git commit --no-verify` — but CI will still fail the PR if lint errors remain. ## Find Something to Work On Start with issues labeled [`good first issue`](https://github.com/rolecraft-sh/rolecraft/labels/good%20first%20issue) — they are small, self-contained, and perfect for new contributors. Don't see anything you like? Open a [feature request](https://github.com/rolecraft-sh/rolecraft/issues/new?template=feature_request.md) or ask in [Discussions](https://github.com/rolecraft-sh/rolecraft/discussions). ## Make Changes - Keep changes focused on a single concern - Follow existing code style (no semicolons, ES modules, zero-dependency runtime) - **Business logic** goes in `src/api/`, **CLI output** goes in `src/commands/` - Add or update tests for any new functionality - Run `npm run lint` and `npm test` before submitting — both must pass - `npm test` uses `node --test`, which walks the whole project, so a new test file is picked up wherever it lives (except inside a dot-directory like `.github/`, which the script names explicitly) - To auto-fix formatting and unused imports, run `npm run lint:fix` ## Error Handling Use `UserError` (from `src/utils/errors.js`) for user-facing errors. It automatically provides helpful suggestions alongside the error message: ```js import { UserError } from '../utils/errors.js' // Instead of: // throw new Error('Failed to fetch npm package') // Do: // throw new UserError('Could not fetch npm package "foo"', { // suggestion: 'Check the package name and your internet connection.', // detail: error.message, // shown with --verbose // code: 'NPM_FETCH_FAILED', // }) ``` | Field | Required | Shown | Purpose | |-------|----------|-------|---------| | `message` | yes | always | What went wrong, user-friendly | | `suggestion` | no | always | What the user should do next | | `detail` | no | `--verbose` | Technical details for debugging | | `code` | no | `--verbose` | Machine-readable error code | Reserve plain `throw new Error(...)` for programming errors (bugs, invariants) that should never reach the user. All user-facing error paths should use `UserError`. > **Tip:** When adding a new command, always use `UserError` for argument validation errors (missing slug, invalid source, etc.). ## Commit Use [conventional commits](https://www.conventionalcommits.org/): ``` feat: add new feature fix: correct bug in parser docs: update installation guide chore: bump dependencies ``` Once your PR is merged, its title becomes a line in the next release's changelog credited to you, and you appear in that release's Contributors list. Nothing extra to do — squash-merge is the default here, and GitHub records you as the commit author. ## Open a Pull Request 1. Push your branch and open a PR against `main` 2. Write a clear title and description explaining what and why 3. Link any related issues 4. Wait for CI checks to pass (Tests + CodeQL) 5. The repository owner will review and merge ## Need Help? - Open a [Discussion](https://github.com/rolecraft-sh/rolecraft/discussions) - Check the [docs site](https://rolecraft-sh.github.io/rolecraft/) ## Code of Conduct Be respectful and constructive. Keep discussions focused on the code. ## What Contributors Say