@deslop/coding-standards
A syntax-only Vite+ lint preset, a strict compiler configuration with Effect diagnostics, and three skills for Claude Code and Codex: lint-companion, pull-requests and review. Installing over a release that shipped writing-code leaves that directory behind; delete it.
Vite+ owns syntax linting and plugin authoring APIs; Effect-patched tsrs owns compiler diagnostics.
vpx @deslop/coding-standards@latest
vp add -D @deslop/coding-standards@latest @effect/tsgo@latest tsrs@latest
import {defineConfig} from 'vite-plus'
import {lint} from '@deslop/coding-standards'
export default defineConfig({lint: {extends: [lint]}})
// package.json
{
"scripts": {
"prepare": "effect-tsgo patch --no-typescript --tsrs",
"typecheck": "tsrs --noEmit --checkerAssignment go",
"check": "vp check && vp run typecheck"
}
}
// tsconfig.json
{"extends": "@deslop/coding-standards/tsconfig.json"}
- Project settings go beside
extends; the preset ignores nothing, so add**/*.gen.tsto your own ignores. - Native rules by name, every category off: tool upgrades opt into nothing. Deslop rules come from the local plugin registry, with no second list of names. Native rules own what they can express; custom rules cover the remaining Effect and React contracts.
- Syntax only.
typescriptplugin rules such asno-explicit-any,consistent-type-importsandmethod-signature-styleneed no type information;typeAware: falsedisables inferred-type rules such asno-floating-promises;typeCheck: falseleaves compiler errors to the Effect-patchedtsrscheck.
Collection performance
no-accumulating-copy checks inline Effect Array.reduce/reduceRight callbacks, including captured accumulator reads in nested callbacks:
-Array.reduce(items, [], (all, item) => [...all, transform(item)])
+Array.map(items, transform)
- Also flags Effect array append/prepend,
Record.setand computed-key record spreads. - Instead:
Array.mapAccumfor stateful selection;MutableList/MutableHashMapfor local collectors. - Valid: scalar folds, persistent
HashMap.set, noncomputed object-property updates. - Intentional snapshots, bounded windows or bounded key sets take a reasoned inline disable; the rule infers no growth and rewrites nothing.
Array.containsis structural; for identity useArray.containsWith(Equivalence.strictEqual()), since a syntax-only preset can't infer the intended equality.