Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/services-layer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ This applies to:
- **Ternary expressions** that pick between fundamentally different messages
- **Lookup tables** keyed on input fields (covered by the string literal union rule above)

> See also: `docs/core/error-system.mdx` § "3b. Avoid Conditional Logic on Factory Inputs" for the canonical reference with full examples.
> See also: `docs/guides/defining-error-vocabularies.mdx` § "Keep the vocabulary closed" for the public guidance on keeping variants distinct.

## Service Implementation Pattern

Expand Down
51 changes: 50 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.1

# Guard against `"wellcrafted": major` changesets while still in 0.x.
# wellcrafted@1.0.0 was published and unpublished on 2025-07-17; npm
Expand Down Expand Up @@ -38,7 +40,54 @@ jobs:
echo "No pre-1.0 major changesets found."

- run: bun install --frozen-lockfile
- run: bun run lint
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
- run: bun run lint:check
- run: bun run format:check
- run: bun run typecheck
- run: bun run build
- run: bun test
- run: bun run docs:examples
- run: bun run docs:exports
- run: bun run docs:claims
- run: bun run docs:snippets
- run: bun run package:smoke
- run: bun run compat:types
- run: bun run compat:runtime

runtime:
name: Runtime (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [22, 24]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.1
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
package-manager-cache: false
- run: bun install --frozen-lockfile
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
- run: bun run build
- run: node scripts/fixtures/runtime/all-subpaths.mjs

docs:
name: Docs (Node 24)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: 24
package-manager-cache: false
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
- run: bun run docs:validate
- run: bun run docs:links
74 changes: 74 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Contributing to wellcrafted

wellcrafted uses Bun for installation, scripts, tests, and release tooling. Consumer setup belongs in the [installation guide](docs/start/installation.mdx); this page covers work inside the repository.

## Set up the repository

CI currently uses Bun 1.3.1. Install dependencies from the lockfile:

```bash
bun install --frozen-lockfile
```

Use `bun install` when intentionally changing dependencies, and commit the resulting `bun.lock` update with the package change.

Mint requires Node.js 24 for local documentation commands. The library's tested runtime matrix is separate from this documentation-tool requirement.

## Run checks

Before opening a pull request, run the checks relevant to your change. The full local pass is:

```bash
bun run lint:check
bun run format:check
bun run typecheck
bun run build
bun test
bun run docs:examples
bun run package:smoke
bun run compat:types
bun run compat:runtime
```

`lint:check` and `format:check` do not write files. Use `bun run lint` and `bun run format` when you want Biome to apply fixes.

Run Mint under Node 24 when documentation changes:

```bash
bun run docs:validate
bun run docs:links
```

Preview the site with `bun run docs:dev`. The command runs the pinned Mint binary from `docs/`.

## Work on documentation

Runnable learning code belongs in `examples/`. Documentation can include or extract that code, but a check must catch drift from the canonical file. Keep partial snippets short and label them when surrounding application code is intentionally omitted.

Each public page should own one reader question:

- `docs/start/` gets a reader installed and through the first Result.
- `docs/guides/` owns task-oriented application workflows.
- `docs/reference/` owns exact current exports and signatures.
- `docs/integrations/` owns third-party boundary adaptation.
- `docs/decisions/` owns design rationale and tradeoffs.

Use lowercase `wellcrafted` in prose. Treat JSON serialization as a convention: `defineErrors` does not enforce JSON-compatible fields, and preserving a JSON shape is separate from runtime validation and end-to-end static typing.

## Add a changeset when behavior changes

Documentation-only changes do not need a changeset. Add one when a pull request changes the installed package's public API or runtime behavior:

```bash
bunx changeset
```

Write the summary for a package consumer. While wellcrafted remains on `0.x`, use a minor changeset for a breaking change rather than a major changeset; CI rejects a major bump because npm cannot reuse the unpublished `1.0.0` version.

Do not run the release script as part of a normal contribution. The release workflow consumes changesets after changes land on `main`.

## Open a focused pull request

Keep the pull request to one coherent change. Explain what changed, why it changed, and the tradeoffs a reviewer should check. Add focused tests for behavior changes and update canonical examples or documentation when a public contract changes.

List the validation commands you actually ran and call out anything you could not run. CI must pass before release automation can publish from `main`.
Loading
Loading