# Contributing ## Setup ```bash git clone https://tangled.org/chadtmiller.com/pds.js cd pds.js && pnpm install npm run build:ui ``` Install with pnpm. The workspace dependencies use the `workspace:*` protocol, and `npm install` fails on it with `EUNSUPPORTEDPROTOCOL`. The `npm run` scripts work normally once pnpm has installed the tree. Run `npm run build:ui` first on a fresh clone. `@pdsjs/account-ui` exports a gitignored bundle, and without it the node and cloudflare entrypoints do not resolve. ## Local development With [`just`](https://github.com/casey/just) and Docker installed, one command starts the whole stack: ```bash just dev # infra, PDS, and a seeded account just dev-down # stop the PDS and remove the docker infra ``` `just dev` starts the docker infra (local PLC, relay, Caddy) and runs the PDS on port 2471. It then registers a mock account with a few records. Open http://localhost:2471/account and sign in with the printed credentials. `just dev` serves a prebuilt account interface. There is no hot reload. After you change interface code, run `npm run build:ui` and refresh the page. For live interface work, run `just dev-live`. It starts the same stack plus a Vite dev server with hot module reload on port 5173. Sign in at http://localhost:5173/account, and your edits reload in the browser. The PDS also restarts on backend edits. Port 2471 and port 5173 are different origins, so you sign in separately on each. Run `just` to see all recipes. `just logs` tails the PDS log.
Setup without just ```bash # Start the local PLC and relay (needs Docker) docker compose up -d # Start the PDS npm run dev:node # Register with the local PLC, in another terminal npm run setup -- --pds https://localhost:3443 --plc-url http://localhost:2582 --relay-url http://localhost:2470 ```
## The commit gate ```bash npm run ci ``` That runs `build:ui`, biome, `tsc --noEmit`, and `test:coverage`. CI runs the same command. Run it before you commit. The full gate is heavy: the git integration tests spawn the real `git` binary against an in-process PDS, and the coverage floors across 195 test files take a few minutes. You do not need it for every local edit. CI enforces it on every push, so iterate with the targeted commands below and run the full gate only before you commit. The individual steps: ```bash npm run check # biome lint + format check npm run format # auto-format npm run lint # lint only npm run typecheck # tsc --noEmit npm test # unit tests npm run test:watch # unit tests, watching ``` Coverage floors are in `vitest.config.js`, per area rather than global. A glob key aggregates every file it matches, so give each module its own entry. ## End-to-end tests The e2e suite is not part of the gate. It needs docker compose. ```bash docker compose up -d npm run test:e2e:node npm run test:e2e:deno npm run test:e2e:cloudflare ``` The suite binds port 2471, so a `just dev` stack blocks it. `npm run test:reference` tests permissioned data against the reference implementation. See [docs/permissioned-data.md](docs/permissioned-data.md). ## Conventions [CLAUDE.md](CLAUDE.md) holds the conventions this repository enforces by review rather than by tooling: what earns a comment, how to phrase one, no `any` in library type annotations, and no em dashes in user-facing copy. [docs/architecture.md](docs/architecture.md) explains the ports and the packages. [docs/pds-decomposition.md](docs/pds-decomposition.md) tracks the handler module work in `core/src/pds.js`. Read it before you take the next cluster. ## Changesets ```bash npm run changeset ``` Describe the change relative to the previous release. That is where "what changed" belongs, rather than in a code comment. ## Project structure ``` packages/ core/ # platform-agnostic core spaces/ # permissioned data (optional) lexicon-resolver/ # lexicon resolution and record validation account-ui/ # account interface node/ # Node.js adapter deno/ # Deno adapter cloudflare/ # Cloudflare adapter readonly/ # read-only server for CAR-backed repositories storage-sqlite/ # SQLite storage adapter blobs-*/ # blob storage adapters examples/ node/ # Node.js example deno/ # Deno example cloudflare/ # Cloudflare example runclub/ # permissioned data demo, two PDSes and a syncing app docker/ # container entrypoint and the local dev stack scripts/ # setup, seeding, and reference tests ```