* chore: prefer es-toolkit helpers and lint the mechanical cases AGENTS.md now names the es-toolkit helpers to reach for instead of hand-written equivalents, and the exceptions: a single clear native call or a measured hot path. The new open-pencil/prefer-es-toolkit rule rejects filter(Boolean) and Set round trips on arrays, the two cases that need no type information, and the existing 45 sites use compact and uniq. tools/ci/policy runs before dependencies are installed, so the rule is off there. * refactor: deduplicate diagnostic categories with uniq * fix: keep es-toolkit out of serialized Playwright callbacks The codemod rewrote a filter(Boolean) inside a page.evaluate callback, which Playwright runs in the page where the compact import does not exist. The spec filters there again, and the rule now skips callbacks passed to evaluate, $eval, $$eval, evaluateHandle, addInitScript and waitForFunction, and filter calls on iterators from values, keys, entries and matchAll, which compact cannot take. * test: write the prefer-es-toolkit cases like the other rule tests Short standalone snippets, as in the base64 and JSON rule tests, instead of a declaration prefix on every case and inline object types. |
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| NOTICE | ||
| package.json | ||
| README.md | ||
OpenPencil lint rules
src/plugin.ts registers locally owned rules; the workspace oxlint.json selects policy. Run bun run --cwd tools/checks/lint test for rule tests and bun run lint for repository enforcement.
Test and type policies
no-module-mockingrejects Bun, Vitest, and Jest module registry mocking, including Bun'smockandjestexports and Vitest'sviandvitestexports. Scoped spies and injected dependencies remain supported. Detection covers direct framework calls and renamed named imports, not arbitrary alias propagation or destructuring.no-reduce-accumulator-copydetects unbounded accumulator copies throughObject.assign,Array.from, and array copy methods. It complementsoxc/no-accumulating-spread. Literal-bounded slices such asslice(0, 2)andslice(-2)are allowed;slice(2)andslice(0, -1)still copy a potentially growing range. This is a conservative syntactic check, not a proof of quadratic runtime for every reducer.no-widen-then-assertdetects immutable local bindings widened to broad types and then asserted narrower in the same function. It intentionally avoids inferring arbitrary type aliases, imported return types, or cross-function flows.
The experimental known-value-widening audit is not included: its broad policy produced too many intentional-contract diagnostics to justify maintaining a separate type resolver.
Maintenance
Upstream attribution and the full license are in NOTICE. These are adapted, locally owned rules, not an automatically synchronized vendor directory. Compare any upstream updates against the recorded commit, preserve local behavior, and add positive and negative regression cases before changing enforcement.
Tests share tests/helpers/lint.ts, which invokes the real Oxlint plugin, rejects parser/configuration failures, and cleans each fixture in finally. Keep test infrastructure out of runtime source helpers.