Add damem notes and skills
Check / check (pull_request) Successful in 37s

This commit is contained in:
Danny Kim
2026-10-16 08:28:47 +09:00
parent 8f23da2b42
commit c02ab9b156
32 changed files with 1241 additions and 4 deletions
+55
View File
@@ -0,0 +1,55 @@
---
description: scripts/project-lint.ts is the repo-local plugin "project" holding the repo's rule list (typed DummyRuleMap) and repo-only rules; never published, no tests
---
Every repo has `scripts/project-lint.ts`, copied from
`cunarist/eslint-plugin-explicit-types` and extended. It is a repo-local
Oxlint plugin with `meta.name` `"project"`, loaded through `jsPlugins` in
`vite.config.ts`. It holds:
- **`configs.project.rules`**: the repo's whole rule list beyond the published
plugin configs: Deno parity rules, extras, per-rule options, and opt-outs,
built-in Oxlint ids included (`curly`, `id-match`, `import/no-cycle`, ...).
- **Custom rules**, enabled as `project/<rule>`. Every repo has
`no-disable-comments` and `no-non-ts-imports`. Apps also port the rules of
their old `scripts/deno-lint-plugin.ts` here under the same names and
behavior (`no-self-sync`, `app-module-conventions`, `restricted-types`, ...).
Rules and plugin stay in this one file; don't add `scripts/rules/`.
```ts
import type { DummyRuleMap } from "vite-plus/lint";
const rules: DummyRuleMap = {
"id-match": ["error", "^_*[^_]*_*$|^[^a-z]*$", {/* ... */}],
curly: "error",
"project/no-disable-comments": "error",
};
const plugin = {
meta: { name: "project" },
rules: { "no-disable-comments": noDisableCommentsRule /* ... */ },
configs: { project: { rules } },
};
export default plugin;
```
## Why `DummyRuleMap` and an unannotated plugin (decided 2026-10-15)
- `DummyRuleMap` (re-exported by `vite-plus/lint`) is Oxlint's type for
`OxlintConfig.rules`. Despite the name it lists every built-in rule with its
options, so a typo in a rule id or option is a type error, not just a CI
failure. Without it, TypeScript widens `"error"` to `string`; `as const`
doesn't help because Oxlint wants mutable tuples.
- `@eslint/core`'s `Plugin` is too loose to read back: `configs` is optional,
any key may be missing, and a config may be an array, so
`projectLint.configs.project.rules` fails in `vite.config.ts` (and `!` is
banned). Optional chaining still leaves the array case.
- Oxlint's own `Plugin` type (`vite-plus/lint/plugins`) has no `configs`.
- Two hand-written interfaces worked but were dropped as noise; a plain
config object was rejected because custom rules need the plugin form anyway
and every repo should look the same.
`scripts/` is tooling, not production code: never packed or published, and
no tests. Narrow `overrides` for `scripts/**` are allowed when a script truly
needs one (e.g. `no-console`); see [[lint-overrides-policy]].