Concise rules the codebase and coding-agent suggestions should follow.
strict typing; no any unless justified with a preceding comment // intentional any: reason.readonly or as const) for constant structures / lookup tables.as X unless unavoidable.createDevice, updateState).is/has/can/should (internal helpers); state flags in this project may keep existing names (intervalOnOff)._ only if intentionally unused yet (silencing oxlint); otherwise export or remove.UPPER_SNAKE_CASE only for process env or true constants; otherwise camelCase.For every public/exported function or public methods (and important internal helpers):
/**
* One‑line summary (starts with a verb, ends without period if short).
*
* Longer description (optional) explaining rationale or algorithm. Mention spec refs if relevant.
*
* Edge cases:
* - bullet 1
* - bullet 2
*
* @param {Type} name Description (units, accepted range, behavior on bounds)
*
* @returns {Type} Description (units, range, side effects)
*/
Rules:
@param and @returns with explicit types (even if TS can infer) for consistency with lint rules.°C * 100, lux, mireds, Pa).@returns {Promise<Type>}.Number.isFinite(n); clamp with Math.min/Math.max.The logger is always AnsiLogger.
log.debug for verbose internal transitions.log.info for state changes & received commands.log.notice for notices.log.warn for recoverable anomalies (out‑of‑range adjusted, missing optional attribute).log.error only for failed operations that stop progress.log.fatal only for failed operations that are not recoverable.oxfmt governs formatting; do not fight the formatter. Run npm run format or check with npm run format:check.oxlint governs linting, including JSDoc, import ordering, TypeScript, Node, Promise, Unicorn, OXC, Jest, and Vitest rules. Run npm run lint; use npm run lint:fix only for focused fixes.tabWidth is 2, printWidth is 180, semicolons are required, single quotes are preferred, and multi-line trailing commas are required.oxfmt: side-effect, builtin, external, internal/subpath, relative, style, unknown.import type for type-only imports. oxlint enforces consistent inline type imports.tsgo is the default TypeScript engine for development validation.npm run typecheck for no-emit type checking (tsgo --build tsconfig.json --noEmit).npm run build for the normal build (tsgo --build tsconfig.build.json).npm run buildProduction still uses tsc for the production build path.converts 100 lux to encoded value).npm run test for the suite, npm run test:coverage for coverage, and pass a test path after -- for targeted validation.Placing this file at root lets coding agents pick patterns. Reinforce by:
// Style: ... comment before a series of helpers.@version only on functional changes, not style edits.@deprecated tag explaining alternative and planned removal version.feat:, fix:, docs:, refactor:, test:, chore: prefix./**
* Convert lux to Matter encoded illuminance value.
*
* Edge cases:
* - <=0 or non-finite -> 0
* - Caps at 0xFFFE
*
* @param {number} lux Illuminance in lux (>=0).
* @returns {number} Encoded value (0..0xFFFE)
*/
function luxToMatterExample(lux: number): number {
if (!Number.isFinite(lux) || lux <= 0) return 0;
return Math.round(Math.min(10000 * Math.log10(lux), 0xfffe));
}
vi.mock / vi.spyOn patterns used by nearby tests.Always use
npm run test:coverage -- yourTest.test.ts
For non-coverage local validation, use:
npm run test -- yourTest.test.ts
Before publish-like changes, the repository uses:
npm run runMeBeforePublish
That runs formatting, linting, HTML updates, clean build, typecheck, and coverage.
Short, opinionated. If a rule isn’t helping, propose a PR to adjust.