{"owner":"boardgameio","repo":"boardgame.io","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to coding agents (e.g. Claude Code) working in this repository.\n\n## Project identity\n\n**boardgame.io** is a turn-based game engine library — game logic lives in `src/`, public entry points in `packages/`, and rollup-built bundles in `dist/`. It is published on npm as `boardgame.io`. The toolchain runs on a modern **Node 24/26** baseline and uses **pnpm** as the package manager.\n\n## Contributing\n\n`CONTRIBUTING.md` governs how changes land, and applies to agent-authored work too. In short:\ncommit to a separate branch rather than `main`, keep each commit to one concern, make sure\n`pnpm test` and `pnpm run lint` pass, and open a Pull Request. Read it before opening one.\n\n## Package manager\n\n**pnpm 10.16+ is mandatory** (pinned via `packageManager` in `package.json`). Don't use npm or yarn — `pnpm-lock.yaml` is the only lockfile, and CI installs with `--frozen-lockfile`. Enable via `corepack enable`.\n\n`.npmrc` sets `minimum-release-age=2880` (48 hours) as supply-chain protection. The integration script overrides this with `--config.minimum-release-age=0` because it installs a local tarball.\n\n**pnpm settings live in `pnpm-workspace.yaml`, not `package.json`.** `overrides`, dependency pins and other pnpm config were moved there in #1273. If pnpm config also exists in `package.json`, `package.json` wins and the workspace file is ignored entirely — so adding a `pnpm.overrides` block to `package.json` silently disables every existing pin (e.g. `jest`) with no warning.\n\n## Common commands\n\n- `pnpm test` — runs `lint` (pretest hook) then jest. Lint failures block tests.\n- `pnpm test:watch` — jest in watch mode (no lint).\n- `pnpm exec jest path/to/file.test.ts` — run one test file. Add `-t \"name\"` for one test case.\n- `pnpm run test:coverage` — lint + jest with coverage scoped to `src/**`. This is what `pre-push` runs, so pushes aren't fast.\n- `pnpm run test:integration` — `scripts/integration.js` deletes `dist/`, `npm pack`s the lib, installs the tarball into `integration/`, and runs that project's tests + build. Use to verify the published artifact.\n- `pnpm run lint` / `pnpm run lint:fix` — eslint over the whole repo (`.eslintrc`).\n- `pnpm run ts` — typecheck only (`tsc --noEmit`).\n- `pnpm run build` — rollup build into `dist/` (silent).\n- `pnpm run build:watch` — rollup in watch mode.\n- `pnpm start` / `pnpm dev` — boots the react-web example (`examples/react-web`) with a dev server. `dev` adds `build:watch`.\n- `pnpm run docs` — local docsify preview.\n\n`pre-commit` runs `lint-staged` (prettier on staged `.ts/.js/.css/.md`). `pre-push` runs full coverage.\n\n## Architecture\n\n### Source layout (`src/`)\n\nAll real code lives under `src/`, split by domain:\n\n- `core/` — pure game engine: the reducer, flow (phases/turns/stages), turn-order strategies, initialization, action creators/types. Framework-agnostic, no I/O.\n- `client/` — client-side runtime, framework bindings (`react.tsx`, `react-native.js`), and **transports** (`transport/local.ts`, `transport/socketio.ts`, `transport/dummy.ts`) that connect a client to either a local in-process master or a remote server.\n- `client/debug/` — Svelte-based debug panel. Svelte sources are transformed by `jest-svelte-transformer.cjs` for tests and via `rollup-plugin-svelte` for builds.\n- `master/` — server-side game authority. The Master applies moves, filters per-player views (`filter-player-view.ts`), and is what both `Local` (in-process) and the socket.io server transport drive.\n- `server/` — Koa-based HTTP API + socket.io transport + DB adapters (`db/flatfile.ts`, `db/inmemory.ts`, `db/localstorage.ts`, plus `db/base.ts` for custom stores).\n- `ai/` — bot framework (`bot.ts`, `random-bot.ts`, `mcts-bot.ts`) plus `Step`/`Simulate` helpers.\n- `plugins/` — plugin system + built-ins (`plugin-immer`, `plugin-random`, `plugin-log`, `plugin-player`, `plugin-events`, `plugin-serializable`). Plugins extend the per-move context (`ctx.G`, `ctx.events`, …).\n- `lobby/`, `testing/` — matchmaking helpers and test utilities.\n- `types.ts` — shared TS types (excluded from coverage).\n\n### Public entry points (`packages/`)\n\nEach `packages/<name>.ts` is a thin re-export file that defines a public subpackage. The canonical list is `subpackages.js`:\n\n```\nclient, core, debug, react, react-native, ai, plugins, master, multiplayer, internal, testing\n```\n\n`packages/server.ts` is built separately (CJS-only, with full node deps). `packages/main.js` is the legacy single-bundle entry.\n\n**To add a new subpackage:** create `packages/<name>.ts`, add `<name>` to `subpackages.js`, and add `<name>` to the `files` array in `package.json`.\n\n### Build pipeline (`rollup.config.js`)\n\nRollup produces four output groups from one config:\n\n1. **Subpackages** → `dist/esm/<name>.js` + `dist/cjs/<name>.js` + `dist/types/packages/<name>.d.ts` (typescript declarations).\n2. **Server** → `dist/cjs/server.js` (CJS only, includes commonjs plugin for node deps).\n3. **Legacy combined** → `dist/boardgameio.js` (CJS) + `dist/boardgameio.es.js` (ESM) from `packages/main.js`.\n4. **Browser UMD** → `dist/boardgameio.min.js`, minified, with `process.env.NODE_ENV` replaced and filesize reporting.\n\n`prepack` runs `build` then `scripts/proxy-dirs.js`, which generates top-level **proxy directories** (`client/`, `core/`, `react/`, …) each containing a tiny `package.json` pointing at `dist/cjs|esm|types`. This is what makes `import 'boardgame.io/client'` work for consumers. These dirs are gitignored but listed in the `files` field for publishing. `postpack` runs `clean`.\n\n### Test setup (jest in `package.json`)\n\n- Preset: `ts-jest/presets/js-with-babel`, env `jsdom`.\n- Svelte: custom `jest-svelte-transformer.cjs` plus `moduleNameMapper` entries pointing `svelte` and `svelte-json-tree-auto` at their client builds.\n- Ignored paths: `examples/`, `integration/`, `node_modules/`, `.npm/`. Don't put real tests in those dirs.\n- Setup files: `jest.setup.js`, `raf/polyfill`, `jest-date-mock`, plus `@testing-library/jest-dom` after env.\n\n### Babel resolver alias\n\n`babel.config.js` aliases `boardgame.io` → `./packages`. This lets `src/` and `examples/` import from the package name as if it were installed, without circular dependencies. Don't import from `dist/` in source.\n\n## Repo gotchas\n\n- **Two pnpm projects nested:** `examples/react-web/` and `integration/` each have their own `pnpm-lock.yaml`. Don't conflate them with the root install.\n- **`*.tgz` is gitignored** because `scripts/integration.js` runs `npm pack` and leaves the tarball in the root. Don't commit it.\n- **Coverage is collected only with the flag.** `pnpm test` (no flag) does not produce coverage; use `pnpm run test:coverage` if a hook or CI expects `coverage/lcov.info`.\n- **The `pretest` hook runs lint**, so a lint error makes `pnpm test` fail before any test runs. Use `pnpm exec jest …` to skip lint when iterating on a single test.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to coding agents (e.g. Claude Code) working in this repository.\n\n## Project identity\n\n**boardgame.io** is a turn-based game engine library — game logic lives in `src/`, public entry points in `packages/`, and rollup-built bundles in `dist/`. It is published on npm as `boardgame.io`. The toolchain runs on a modern **Node 24/26** baseline and uses **pnpm** as the package manager.\n\n## Contributing\n\n`CONTRIBUTING.md` governs how changes land, and applies to agent-authored work too. In short:\ncommit to a separate branch rather than `main`, keep each commit to one concern, make sure\n`pnpm test` and `pnpm run lint` pass, and open a Pull Request. Read it before opening one.\n\n## Package manager\n\n**pnpm 10.16+ is mandatory** (pinned via `packageManager` in `package.json`). Don't use npm or yarn — `pnpm-lock.yaml` is the only lockfile, and CI installs with `--frozen-lockfile`. Enable via `corepack enable`.\n\n`.npmrc` sets `minimum-release-age=2880` (48 hours) as supply-chain protection. The integration script overrides this with `--config.minimum-release-age=0` because it installs a local tarball.\n\n**pnpm settings live in `pnpm-workspace.yaml`, not `package.json`.** `overrides`, dependency pins and other pnpm config were moved there in #1273. If pnpm config also exists in `package.json`, `package.json` wins and the workspace file is ignored entirely — so adding a `pnpm.overrides` block to `package.json` silently disables every existing pin (e.g. `jest`) with no warning.\n\n## Common commands\n\n- `pnpm test` — runs `lint` (pretest hook) then jest. Lint failures block tests.\n- `pnpm test:watch` — jest in watch mode (no lint).\n- `pnpm exec jest path/to/file.test.ts` — run one test file. Add `-t \"name\"` for one test case.\n- `pnpm run test:coverage` — lint + jest with coverage scoped to `src/**`. This is what `pre-push` runs, so pushes aren't fast.\n- `pnpm run test:integration` — `scripts/integration.js` deletes `dist/`, `npm pack`s the lib, installs the tarball into `integration/`, and runs that project's tests + build. Use to verify the published artifact.\n- `pnpm run lint` / `pnpm run lint:fix` — eslint over the whole repo (`.eslintrc`).\n- `pnpm run ts` — typecheck only (`tsc --noEmit`).\n- `pnpm run build` — rollup build into `dist/` (silent).\n- `pnpm run build:watch` — rollup in watch mode.\n- `pnpm start` / `pnpm dev` — boots the react-web example (`examples/react-web`) with a dev server. `dev` adds `build:watch`.\n- `pnpm run docs` — local docsify preview.\n\n`pre-commit` runs `lint-staged` (prettier on staged `.ts/.js/.css/.md`). `pre-push` runs full coverage.\n\n## Architecture\n\n### Source layout (`src/`)\n\nAll real code lives under `src/`, split by domain:\n\n- `core/` — pure game engine: the reducer, flow (phases/turns/stages), turn-order strategies, initialization, action creators/types. Framework-agnostic, no I/O.\n- `client/` — client-side runtime, framework bindings (`react.tsx`, `react-native.js`), and **transports** (`transport/local.ts`, `transport/socketio.ts`, `transport/dummy.ts`) that connect a client to either a local in-process master or a remote server.\n- `client/debug/` — Svelte-based debug panel. Svelte sources are transformed by `jest-svelte-transformer.cjs` for tests and via `rollup-plugin-svelte` for builds.\n- `master/` — server-side game authority. The Master applies moves, filters per-player views (`filter-player-view.ts`), and is what both `Local` (in-process) and the socket.io server transport drive.\n- `server/` — Koa-based HTTP API + socket.io transport + DB adapters (`db/flatfile.ts`, `db/inmemory.ts`, `db/localstorage.ts`, plus `db/base.ts` for custom stores).\n- `ai/` — bot framework (`bot.ts`, `random-bot.ts`, `mcts-bot.ts`) plus `Step`/`Simulate` helpers.\n- `plugins/` — plugin system + built-ins (`plugin-immer`, `plugin-random`, `plugin-log`, `plugin-player`, `plugin-events`, `plugin-serializable`). Plugins extend the per-move context (`ctx.G`, `ctx.events`, …).\n- `lobby/`, `testing/` — matchmaking helpers and test utilities.\n- `types.ts` — shared TS types (excluded from coverage).\n\n### Public entry points (`packages/`)\n\nEach `packages/<name>.ts` is a thin re-export file that defines a public subpackage. The canonical list is `subpackages.js`:\n\n```\nclient, core, debug, react, react-native, ai, plugins, master, multiplayer, internal, testing\n```\n\n`packages/server.ts` is built separately (CJS-only, with full node deps). `packages/main.js` is the legacy single-bundle entry.\n\n**To add a new subpackage:** create `packages/<name>.ts`, add `<name>` to `subpackages.js`, and add `<name>` to the `files` array in `package.json`.\n\n### Build pipeline (`rollup.config.js`)\n\nRollup produces four output groups from one config:\n\n1. **Subpackages** → `dist/esm/<name>.js` + `dist/cjs/<name>.js` + `dist/types/packages/<name>.d.ts` (typescript declarations).\n2. **Server** → `dist/cjs/server.js` (CJS only, includes commonjs plugin for node deps).\n3. **Legacy combined** → `dist/boardgameio.js` (CJS) + `dist/boardgameio.es.js` (ESM) from `packages/main.js`.\n4. **Browser UMD** → `dist/boardgameio.min.js`, minified, with `process.env.NODE_ENV` replaced and filesize reporting.\n\n`prepack` runs `build` then `scripts/proxy-dirs.js`, which generates top-level **proxy directories** (`client/`, `core/`, `react/`, …) each containing a tiny `package.json` pointing at `dist/cjs|esm|types`. This is what makes `import 'boardgame.io/client'` work for consumers. These dirs are gitignored but listed in the `files` field for publishing. `postpack` runs `clean`.\n\n### Test setup (jest in `package.json`)\n\n- Preset: `ts-jest/presets/js-with-babel`, env `jsdom`.\n- Svelte: custom `jest-svelte-transformer.cjs` plus `moduleNameMapper` entries pointing `svelte` and `svelte-json-tree-auto` at their client builds.\n- Ignored paths: `examples/`, `integration/`, `node_modules/`, `.npm/`. Don't put real tests in those dirs.\n- Setup files: `jest.setup.js`, `raf/polyfill`, `jest-date-mock`, plus `@testing-library/jest-dom` after env.\n\n### Babel resolver alias\n\n`babel.config.js` aliases `boardgame.io` → `./packages`. This lets `src/` and `examples/` import from the package name as if it were installed, without circular dependencies. Don't import from `dist/` in source.\n\n## Repo gotchas\n\n- **Two pnpm projects nested:** `examples/react-web/` and `integration/` each have their own `pnpm-lock.yaml`. Don't conflate them with the root install.\n- **`*.tgz` is gitignored** because `scripts/integration.js` runs `npm pack` and leaves the tarball in the root. Don't commit it.\n- **Coverage is collected only with the flag.** `pnpm test` (no flag) does not produce coverage; use `pnpm run test:coverage` if a hook or CI expects `coverage/lcov.info`.\n- **The `pretest` hook runs lint**, so a lint error makes `pnpm test` fail before any test runs. Use `pnpm exec jest …` to skip lint when iterating on a single test.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file provides guidance to coding agents (e.g. Claude Code) working in this repository.\n\n## Project identity\n\n**boardgame.io** is a turn-based game engine library — game logic lives in `src/`, public entry points in `packages/`, and rollup-built bundles in `dist/`. It is published on npm as `boardgame.io`. The toolchain runs on a modern **Node 24/26** baseline and uses **pnpm** as the package manager.\n\n## Contributing\n\n`CONTRIBUTING.md` governs how changes land, and applies to agent-authored work too. In short:\ncommit to a separate branch rather than `main`, keep each commit to one concern, make sure\n`pnpm test` and `pnpm run lint` pass, and open a Pull Request. Read it before opening one.\n\n## Package manager\n\n**pnpm 10.16+ is mandatory** (pinned via `packageManager` in `package.json`). Don't use npm or yarn — `pnpm-lock.yaml` is the only lockfile, and CI installs with `--frozen-lockfile`. Enable via `corepack enable`.\n\n`.npmrc` sets `minimum-release-age=2880` (48 hours) as supply-chain protection. The integration script overrides this with `--config.minimum-release-age=0` because it installs a local tarball.\n\n**pnpm settings live in `pnpm-workspace.yaml`, not `package.json`.** `overrides`, dependency pins and other pnpm config were moved there in #1273. If pnpm config also exists in `package.json`, `package.json` wins and the workspace file is ignored entirely — so adding a `pnpm.overrides` block to `package.json` silently disables every existing pin (e.g. `jest`) with no warning.\n\n## Common commands\n\n- `pnpm test` — runs `lint` (pretest hook) then jest. Lint failures block tests.\n- `pnpm test:watch` — jest in watch mode (no lint).\n- `pnpm exec jest path/to/file.test.ts` — run one test file. Add `-t \"name\"` for one test case.\n- `pnpm run test:coverage` — lint + jest with coverage scoped to `src/**`. This is what `pre-push` runs, so pushes aren't fast.\n- `pnpm run test:integration` — `scripts/integration.js` deletes `dist/`, `npm pack`s the lib, installs the tarball into `integration/`, and runs that project's tests + build. Use to verify the published artifact.\n- `pnpm run lint` / `pnpm run lint:fix` — eslint over the whole repo (`.eslintrc`).\n- `pnpm run ts` — typecheck only (`tsc --noEmit`).\n- `pnpm run build` — rollup build into `dist/` (silent).\n- `pnpm run build:watch` — rollup in watch mode.\n- `pnpm start` / `pnpm dev` — boots the react-web example (`examples/react-web`) with a dev server. `dev` adds `build:watch`.\n- `pnpm run docs` — local docsify preview.\n\n`pre-commit` runs `lint-staged` (prettier on staged `.ts/.js/.css/.md`). `pre-push` runs full coverage.\n\n## Architecture\n\n### Source layout (`src/`)\n\nAll real code lives under `src/`, split by domain:\n\n- `core/` — pure game engine: the reducer, flow (phases/turns/stages), turn-order strategies, initialization, action creators/types. Framework-agnostic, no I/O.\n- `client/` — client-side runtime, framework bindings (`react.tsx`, `react-native.js`), and **transports** (`transport/local.ts`, `transport/socketio.ts`, `transport/dummy.ts`) that connect a client to either a local in-process master or a remote server.\n- `client/debug/` — Svelte-based debug panel. Svelte sources are transformed by `jest-svelte-transformer.cjs` for tests and via `rollup-plugin-svelte` for builds.\n- `master/` — server-side game authority. The Master applies moves, filters per-player views (`filter-player-view.ts`), and is what both `Local` (in-process) and the socket.io server transport drive.\n- `server/` — Koa-based HTTP API + socket.io transport + DB adapters (`db/flatfile.ts`, `db/inmemory.ts`, `db/localstorage.ts`, plus `db/base.ts` for custom stores).\n- `ai/` — bot framework (`bot.ts`, `random-bot.ts`, `mcts-bot.ts`) plus `Step`/`Simulate` helpers.\n- `plugins/` — plugin system + built-ins (`plugin-immer`, `plugin-random`, `plugin-log`, `plugin-player`, `plugin-events`, `plugin-serializable`). Plugins extend the per-move context (`ctx.G`, `ctx.events`, …).\n- `lobby/`, `testing/` — matchmaking helpers and test utilities.\n- `types.ts` — shared TS types (excluded from coverage).\n\n### Public entry points (`packages/`)\n\nEach `packages/<name>.ts` is a thin re-export file that defines a public subpackage. The canonical list is `subpackages.js`:\n\n```\nclient, core, debug, react, react-native, ai, plugins, master, multiplayer, internal, testing\n```\n\n`packages/server.ts` is built separately (CJS-only, with full node deps). `packages/main.js` is the legacy single-bundle entry.\n\n**To add a new subpackage:** create `packages/<name>.ts`, add `<name>` to `subpackages.js`, and add `<name>` to the `files` array in `package.json`.\n\n### Build pipeline (`rollup.config.js`)\n\nRollup produces four output groups from one config:\n\n1. **Subpackages** → `dist/esm/<name>.js` + `dist/cjs/<name>.js` + `dist/types/packages/<name>.d.ts` (typescript declarations).\n2. **Server** → `dist/cjs/server.js` (CJS only, includes commonjs plugin for node deps).\n3. **Legacy combined** → `dist/boardgameio.js` (CJS) + `dist/boardgameio.es.js` (ESM) from `packages/main.js`.\n4. **Browser UMD** → `dist/boardgameio.min.js`, minified, with `process.env.NODE_ENV` replaced and filesize reporting.\n\n`prepack` runs `build` then `scripts/proxy-dirs.js`, which generates top-level **proxy directories** (`client/`, `core/`, `react/`, …) each containing a tiny `package.json` pointing at `dist/cjs|esm|types`. This is what makes `import 'boardgame.io/client'` work for consumers. These dirs are gitignored but listed in the `files` field for publishing. `postpack` runs `clean`.\n\n### Test setup (jest in `package.json`)\n\n- Preset: `ts-jest/presets/js-with-babel`, env `jsdom`.\n- Svelte: custom `jest-svelte-transformer.cjs` plus `moduleNameMapper` entries pointing `svelte` and `svelte-json-tree-auto` at their client builds.\n- Ignored paths: `examples/`, `integration/`, `node_modules/`, `.npm/`. Don't put real tests in those dirs.\n- Setup files: `jest.setup.js`, `raf/polyfill`, `jest-date-mock`, plus `@testing-library/jest-dom` after env.\n\n### Babel resolver alias\n\n`babel.config.js` aliases `boardgame.io` → `./packages`. This lets `src/` and `examples/` import from the package name as if it were installed, without circular dependencies. Don't import from `dist/` in source.\n\n## Repo gotchas\n\n- **Two pnpm projects nested:** `examples/react-web/` and `integration/` each have their own `pnpm-lock.yaml`. Don't conflate them with the root install.\n- **`*.tgz` is gitignored** because `scripts/integration.js` runs `npm pack` and leaves the tarball in the root. Don't commit it.\n- **Coverage is collected only with the flag.** `pnpm test` (no flag) does not produce coverage; use `pnpm run test:coverage` if a hook or CI expects `coverage/lcov.info`.\n- **The `pretest` hook runs lint**, so a lint error makes `pnpm test` fail before any test runs. Use `pnpm exec jest …` to skip lint when iterating on a single test.\n","category":"root","tokens":1729}]}