This file defines repository-wide rules only. For any change, read this file first, then read the
nearest AGENTS.md in the subtree you are editing.
- The root
AGENTS.mdowns stable repo-wide policy. lib/*/AGENTS.md,packages/**/AGENTS.md, andimplementations/*/AGENTS.mdown local instructions, commands, and gotchas.- If local guidance conflicts with this file, follow the more specific
AGENTS.mdfor that subtree. - When adding a new workspace package or implementation, add a sibling
AGENTS.mdin the same change. - Keep child
AGENTS.mdfiles focused on local behavior. Do not duplicate root policy unless the subtree has a local exception.
- Use the Node version from
.nvmrcwhen possible. Repository engine constraints live in the rootpackage.json. - Use
pnpmonly. The pinned package-manager version lives in the rootpackage.json. - Prefer
pnpm <script>overpnpm run <script>when both forms are equivalent. - Prefer
rgandrg --filesfor code search. .envfiles are ignored. Start from the checked-in.env.examplewhere applicable, and do not overwrite an existing.envwithout a clear reason.- Some implementations have additional runtime prerequisites or process-management expectations. See
the relevant implementation
AGENTS.mdbefore running local app or E2E flows.
- Shared libraries and published SDK packages live under
lib/andpackages/. - Reference implementations live under
implementations/. - Implementations consume local package tarballs from
pkgs/afterpnpm build:pkgsand implementation install steps. - Generated outputs such as
dist/,coverage/,docs/,pkgs/,playwright-report/, andtest-results/are not the source of truth.
Prefer editing source files and configuration:
src/**e2e/**__tests__/**scripts/**documentation/**README.mdpackage.jsontsconfig*.jsonrstest.config.tsplaywright.config.mjseslint.config.ts.prettierrc.github/workflows/**
Do not hand-edit generated or local-only artifacts unless the task is explicitly about them:
dist/**coverage/**docs/**pkgs/**.rslib/**.rsdoctor/**node_modules/**- local
.envfiles
- Treat
eslint.config.tsas an upfront design constraint, not a cleanup step after coding. - Before editing TypeScript or TSX in an unfamiliar area, skim
eslint.config.tsand nearby files to match existing idioms. - Prefer code that naturally satisfies the rules over later suppression or churn.
- For isolated lint findings, start with the smallest AST-local fix possible. Prefer changing the flagged expression, declaration, or statement before considering any surrounding refactor.
- If the first local rewrite fails, inspect the exact rule configuration and error location before trying broader changes.
- Do not broaden a one-line lint fix into helper rewrites, data-flow changes, or nearby refactors unless the minimal local options are exhausted and there is a clear semantic reason to do so.
- Match existing local patterns before introducing new ones. In this repo, that usually means:
- prefix intentionally unused variables, parameters, caught errors, and array slots with
_ - avoid introducing unexplained magic numbers in production code; extract named constants when the value is not obviously one of the common allowed literals
- keep strict typed-code hygiene and avoid broad
any-style shortcuts - rely on Prettier and
prettier-plugin-organize-importsfor formatting and import order rather than manual styling
- prefix intentionally unused variables, parameters, caught errors, and array slots with
- Never add
eslint-disable,eslint-disable-next-line, oreslint-disable-linecomments unless the user explicitly instructs you to do so. - If a lint fix stops being small and local, stop and reassess instead of escalating into trial-and- error rewrites.
- Do not copy test-only patterns into production code. Test and E2E files have targeted rule relaxations that do not apply elsewhere.
- If code keeps fighting the linter, stop and rewrite the approach to match repository patterns rather than stacking fixes.
- Run the smallest meaningful validation that matches the change.
- When linting or formatting is likely needed, prefer the smallest fix-enabled command that matches the edited area first, then confirm with a check-only command if needed. Avoid the pattern of running a pure check, then rerunning the same tool again only to apply obvious auto-fixes.
- For TypeScript or TSX edits, run the relevant lint command early enough to influence the shape of the implementation, not only at the end.
- For
lib/orpackages/edits, preferpnpm lintafter the first meaningful patch and again before finishing if the change grew. - For
implementations/edits, preferpnpm implementation:lintafter the first meaningful patch and again before finishing if the change grew. - For a single workspace package, prefer targeted
typecheck,test:unit, andbuild. - For built workspace packages, run the package
size:checkscript when runtime code, published dependencies, bundler config, exports, or bundle shape changes. - For cross-cutting changes, broaden validation to affected downstream packages or implementations.
- For package changes used by implementations, run
pnpm build:pkgsbefore reinstalling or running implementation tests. - For implementation-only changes, use
pnpm implementation:lint, targeted implementationtypecheck, and targeted E2E as needed. - If you skip a relevant check because of time or environment constraints, say exactly what was not run and why.
High-signal repo-wide commands:
pnpm lintpnpm typecheckpnpm test:unitpnpm buildpnpm size:checkpnpm build:pkgspnpm format:checkpnpm docs:generate
- Do not rerun the same failing command unchanged more than once.
- Before retrying, classify the failure into one of these buckets:
- command resolution or PATH
- missing prerequisite or setup
- permission or sandbox
- expected long-running process
- transient network or external-service failure
- stale local state, artifact, or process conflict
- unknown
- Prefer a small probe before a full rerun. Check the nearest
AGENTS.md, the targetpackage.json, and any relevantREADME.mdorCONTRIBUTING.mdsection before guessing. - If a lint or format command fails with findings that the tool can auto-fix, prefer a targeted fix-enabled rerun over repeated check-only runs, then revalidate once.
- If the shell reports a command as missing:
- first prefer
pnpm <script>orpnpm exec <tool>over assuming a global binary - check whether the command is defined in the relevant
package.json - do not install new global tools to work around a missing PATH entry unless the user explicitly asked for that setup
- if the tool is absent and not documented as a prerequisite, stop and report instead of improvising
- first prefer
- If a documented prerequisite is missing, run that prerequisite once, then retry the original
command once. Common repository prerequisites include:
pnpm installpnpm build:pkgspnpm implementation:install- a local
.envcopied from.env.example - implementation-specific setup documented in the nearest child
AGENTS.md
- If the error suggests a permissions or sandbox problem, such as
EACCES,EPERM, network blocking, or write denial, do not keep retrying. Request approval or escalation on the next attempt rather than searching for workarounds. - If a command is supposed to stay alive, such as a dev server, watcher, mock server, preview server, or emulator tooling, treat continued execution as expected behavior. Poll or inspect logs instead of restarting it repeatedly.
- If a failure looks transient, such as a registry timeout or flaky external network call, retry at most once. If it fails again, stop and report the blocker.
- Before cleanup, decide whether the issue is stale state. Prefer targeted cleanup of only the
artifacts or processes created by the failed flow. Do not delete unrelated outputs, local
.envfiles, or use broad cleanup such aspm2 delete all. - After two failed attempts with the same strategy, stop and summarize:
- the exact command
- the failure class
- the relevant stderr or symptom
- what you already tried
- the smallest next action, user input, or approval needed
Common repo-specific failure modes:
- An implementation does not reflect a package change: run
pnpm build:pkgs, then rerun the relevantpnpm implementation:run -- <implementation> implementation:install. - If the goal is E2E setup rather than the narrowest possible refresh step, prefer the combined root
wrapper
pnpm setup:e2e:<implementation>. For a full E2E run, preferpnpm test:e2e:<implementation>. - Implementation-specific runtime failures such as Docker availability, Playwright browser setup,
emulator requirements,
.envdrift, PM2 state, and local port conflicts belong in the relevant implementationAGENTS.md, not here.
- When public SDK behavior changes, update the relevant TSDoc or JSDoc and the affected package
README.mdin the same change. - Authored supporting docs live in
documentation/; generated TypeDoc output lives indocs/. - If a package includes a package-local dev harness or other meaningful local dev surface, keep that surface relevant to the current SDK behavior and update it in the same change when the package's developer-facing flows, configuration, or core capabilities change.
- If the repository later adds any replacement design, architecture, or specification artifacts for the changed area, keep them aligned in the same change.
docs/is generated by TypeDoc and is gitignored.- Implementation E2E in
.github/workflows/main-pipeline.yamlis intentionally path-filtered. If a change should alter E2E coverage, update the workflow and keep it aligned with CONTRIBUTING.md.
- Never overwrite or delete ignored local files just to get a clean run.
- Do not run destructive Contentful scripts unless explicitly asked.
- Do not use broad cleanup commands such as
pm2 delete allunless explicitly asked. - Do not assume full cross-platform E2E is required for every change.
- Read the root
AGENTS.md. - Read the nearest
AGENTS.mdin the subtree you will edit. - Make the narrowest source-of-truth change in the correct layer.
- Run the smallest meaningful validation set.
- Broaden validation only when exports, build tooling, mocks, or shared behavior changed.
- Summarize what changed, what was verified, what was skipped, and any follow-up risk.