|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Rules for coding agents that the code and config don't already state. Keep it |
| 4 | +that way: a constraint that can live in a comment next to the thing it |
| 5 | +constrains belongs there, not here. |
| 6 | + |
| 7 | +## Writing |
| 8 | + |
| 9 | +- NZ English everywhere ("colour", "behaviour", "initialise"). |
| 10 | +- Single-line commit messages, `git log --oneline` style. Add a body only to |
| 11 | + explain why, and only for behaviour or type changes. |
| 12 | +- No conventional-commit prefixes (`feat:`, `fix:`, `chore(deps):`) in commit |
| 13 | + subjects or PR titles. Write a plain capitalised sentence. Nothing reads the |
| 14 | + prefix: the version bump comes from the PR label, and renovate is set to |
| 15 | + `semanticCommits: "disabled"` to match. |
| 16 | +- PR titles are copied verbatim into `CHANGELOG.md`, so write them as the |
| 17 | + changelog line you want readers to see. |
| 18 | +- Hard-wrap commit message bodies at 72 columns; `git log` does not reflow |
| 19 | + them. Do not hard-wrap PR or issue descriptions: GitHub reflows markdown, |
| 20 | + and its web editor leaves wrapped source ragged once anyone edits it. |
| 21 | + |
| 22 | +## Architecture |
| 23 | + |
| 24 | +Injection happens in a single effect in `src/ReactSVG.tsx`. The two-wrapper |
| 25 | +structure, outer managed by React and inner managed by `@tanem/svg-injector`, |
| 26 | +is load-bearing: don't collapse it. |
| 27 | + |
| 28 | +That file's comments cover the rest: why `forwardRef` is required, why the |
| 29 | +effect's dependency list is deliberately narrow, why the callbacks are read |
| 30 | +through a ref, and what the teardown guard protects. Read them before changing |
| 31 | +the injection flow. |
| 32 | + |
| 33 | +## Build & test |
| 34 | + |
| 35 | +`npm run test:src` is the development loop. `npm test` is the full gate. |
| 36 | +`npm run test:react` runs the React matrix and is slow enough to be |
| 37 | +pre-release only. `npm run size`, `npm run test:dist` and the `package:*` |
| 38 | +checks read `dist/`, so they need a current `npm run build`. A new spec that |
| 39 | +reads `dist/` goes in `config/jest/dist-tests.js`, which keeps it out of |
| 40 | +`test:src`. |
| 41 | + |
| 42 | +Give each test its own `faker.seed()` and a `faker.string.uuid()` SVG URL, or |
| 43 | +svg-injector's cache leaks state between tests. Injection is async: assert |
| 44 | +through `await waitFor(...)`. |
| 45 | + |
| 46 | +Raising a `size-limit` budget in `package.json` is a decision, not a fix. Find |
| 47 | +what grew first, and say why in the commit message. |
| 48 | + |
| 49 | +The React matrix covers boundary versions only: the first and last minor of |
| 50 | +each supported major, plus minors that changed behaviour. Currently 16.8, |
| 51 | +16.14, 17.0, 18.0, 18.3, 19.0, 19.1. Adding a boundary means replacing the |
| 52 | +previous last-minor for that major, not accumulating versions. Copy a sibling |
| 53 | +`test/react/<version>/package.json`, and see `scripts/test-react.ts` for how a |
| 54 | +single version is run. |
| 55 | + |
| 56 | +## Releases |
| 57 | + |
| 58 | +`npm run release` runs on a Monday cron against `master`. It takes the version |
| 59 | +bump from the labels on PRs merged since the last tag, then regenerates |
| 60 | +`CHANGELOG.md` and `AUTHORS` and bumps `version` in `package.json` and |
| 61 | +`package-lock.json`. |
| 62 | + |
| 63 | +- Exactly one label per PR. None, or more than one, throws and blocks the |
| 64 | + release for everything merged alongside it. `breaking` gives a major, |
| 65 | + `enhancement` a minor, `bug` / `documentation` / `internal` a patch. Tooling, |
| 66 | + CI and dependency work is `internal`. |
| 67 | +- Never hand-edit `CHANGELOG.md`, `AUTHORS` or either `version` field. |
| 68 | +- Breaking changes need a `MIGRATION.md` entry in the same PR: the generated |
| 69 | + changelog is only a list of PR titles. |
| 70 | + |
| 71 | +## Dependencies |
| 72 | + |
| 73 | +Pin `devDependencies` to exact versions. Keep `dependencies` on caret ranges. |
| 74 | + |
| 75 | +## Examples |
| 76 | + |
| 77 | +`examples/` are built to open on CodeSandbox, so their platform dependencies |
| 78 | +(vite, @vitejs/plugin-react, next, typescript, @types/react, @types/react-dom) |
| 79 | +track the official |
| 80 | +[sandbox-templates](https://github.com/codesandbox/sandbox-templates/tree/main): |
| 81 | +`react-vite` / `react-vite-ts` for the Vite examples, `nextjs` for the SSR one. |
| 82 | +Don't bump those past the template, except for patch-level security fixes |
| 83 | +inside the template's major.minor. Example-only dependencies |
| 84 | +(`styled-components`, `glamor`, `react-frame-component`) aren't governed by it. |
| 85 | + |
| 86 | +Renovate skips `examples/**`, so updates are manual: do every example in one |
| 87 | +commit and check at least one still opens on CodeSandbox. |
| 88 | + |
| 89 | +## Conventions |
| 90 | + |
| 91 | +- `src/types.ts` is the only prop contract. There is no runtime `propTypes`. |
| 92 | +- Keep `Props` flat. It extends `HTMLAttributes` and `SVGAttributes`, and |
| 93 | + nesting it trips excessive-depth errors in wrapper libraries. |
0 commit comments