5.3 KiB
5.3 KiB
description: Lint config shape: every non-nursery Oxlint category on, plugins via all, a blacklist of offs in configs.project, per-file exceptions only in projectOverrides, ignorePatterns only for generated output
Policy (2026-10-19): a blacklist, not a whitelist. Replaces the older category-subset and "no overrides" notes.
- Categories:
correctness,suspicious,pedantic,perf,style,restrictionaterror.nurserystays off (no line for it). - Plugins are enabled whole through their
allconfig (explicitTypes.configs.all.rules,importStructure.configs.all.rules). - Blacklist: repo-wide offs and option tweaks live in
projectLint.configs.project.rulesinscripts/project-lint.ts, spread last inrules, each with a one-line reason. Never re-list a rule a category already turns on. bot-agents runs on Node everywhere, soimport/no-nodejs-modules,unicorn/no-process-exit, andno-consoleare off repo-wide. - Per-file exceptions only via
projectOverrides, the wholeoverridesarray exported fromscripts/project-lint.ts: the Node code entry (vite.config.ts,scripts/**,nodeRules) first, then one entry per exception with a why-comment.vite.config.tshas exactlyoverrides: projectOverrides. - No
allowFilesoptions in custom rules, and no disable comments (lint-no-disable-comments). ignorePatternsonly for generated or build output, never hand-written code. A hand-written file is linted, with override entries for only what it legitimately breaks. bot-agents has no generated code, so none.- Precedence: categories <
rules(a later spread wins) <overrides(a later entry wins). - Size and complexity limits (
complexity,max-lines, ...) are set to the smallest value the current code passes.
// scripts/project-lint.ts
export const projectOverrides: OxlintOverride[] = [
{ files: ["vite.config.ts", "scripts/**"], rules: nodeRules },
// Why: src/example.ts must ... (a per-file exception, if one is ever needed)
// { files: ["src/example.ts"], rules: { "some-rule": "off" } },
];
// vite.config.ts
rules: {
...explicitTypes.configs.all.rules,
...importStructure.configs.all.rules,
...projectLint.configs.project.rules,
},
overrides: projectOverrides,
Rule decisions (2026-10-19, all repos)
typescript/promise-function-asyncis on withrequire-awaitandtypescript/return-await. A function that returns a promise isasyncand awaits it:async f() { const x = await g(); return x; }. Test doubles do the same (const resolved = await Promise.resolve(v); return resolved;), andexpect(promise).rejectstakes the promise itself.src/processes/child.tsis exempt inprojectOverrides:exitCodemust return the very promise it marks handled, or a failed spawn would surface as an unhandled rejection before callers await it.init-declarationsis on: an uninitializedletbecomeslet x: T | null = null;(unknownalready includesnull); atrythat assigns and acatchthat exits still narrow it.no-use-before-defineis on with only{ functions: false }.no-await-in-loopis off (sequential awaits are intentional) andunicorn/no-array-reduceis on: sequential steps are plainforloops, neverreducechains or recursion.consistent-return,typescript/switch-exhaustiveness-check, anddefault-caseare off: TypeScript's checks cover them, and nodefault:branch is added to an exhaustive switch.unknownis allowed;anyis banned and thetypescript/no-unsafe-*rules are on. Untrusted data isunknownplus a type guard.unicorn/no-array-for-each(usefor...of),unicorn/prefer-structured-clone, andtypescript/prefer-nullish-coalescing(defaults) stay on.- explicit-types
upper-snake-string-unionsis on (enum-values-upper-snake);unicorn/custom-error-definitionis on, so a custom error has a constructor that setsthis.name. src/post/andsrc/profiles/(code and tests) are exempt fromproject/prefer-asciiinprojectOverrides: posted Gitea text shows emoji verdict marks and a middle dot.
Rule decisions (2026-10-20, all repos)
unicorn/number-literal-caseis off: Oxfmt lowercases hex digits back.typescript/consistent-returnis off too: it misfires on complete switches, likeconsistent-return.- On with defaults, no offs:
prefer-object-spread,unicorn/prefer-spread,unicorn/no-useless-spread,typescript/no-misused-spread,no-plusplus(x += 1),unicorn/no-array-method-this-argument,typescript/method-signature-style("property"),typescript/unified-signatures. unicorn/import-styleuses its default:import nodePath from "node:path"andnodePath.join(...)(nodePath, sincepathis a common variable).no-template-curly-in-stringis on; onlytests/workflow.test.ts, which checks literal Gitea${{ }}expressions, is exempt inprojectOverrides.- Rule defaults are preferred over option tweaks unless a tweak is needed.
fmtmatchesdeno fmt:printWidth: 80,quoteProps: "preserve",embeddedLanguageFormatting: "off".max-lines-per-functionis 124 after the narrower width.
A new category hit is fixed in the code; an off or exception is added only for a real collision or churn, with its reason. Rules: project-lint-plugin.