@avi2dg/checks 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +66 -40
  2. package/CONTRIBUTING.md +14 -10
  3. package/README.md +15 -24
  4. package/bunfig.toml +1 -1
  5. package/dist/effect-channel/index.js +122 -0
  6. package/dist/{index.js → readability/index.js} +8 -120
  7. package/docs/configs/commit-messages.md +5 -1
  8. package/docs/configs/dependency-rules.md +5 -2
  9. package/docs/configs/effect-rules.md +32 -33
  10. package/docs/configs/native-settings.md +74 -0
  11. package/docs/configs/typescript-rules.md +4 -0
  12. package/docs/design.md +26 -27
  13. package/docs/gates/checks-backtest.md +4 -0
  14. package/docs/gates/checks-ci-wiring.md +30 -93
  15. package/docs/gates/checks-comment-gate.md +4 -0
  16. package/docs/gates/checks-commit-identity.md +23 -27
  17. package/docs/gates/checks-docs.md +23 -21
  18. package/docs/gates/checks-flake.md +4 -10
  19. package/docs/gates/checks-lint-coverage.md +5 -1
  20. package/docs/gates/checks-lint.md +22 -104
  21. package/docs/gates/checks-mutation-compare.md +4 -0
  22. package/docs/gates/checks-quarantine-clock.md +4 -0
  23. package/docs/gates/checks-repetition.md +27 -41
  24. package/docs/gates/checks-subsumed-tests.md +4 -0
  25. package/docs/gates/checks-suppressions-ratchet.md +4 -0
  26. package/docs/gates/checks-test-layout.md +16 -8
  27. package/docs/gates/checks-test.md +68 -36
  28. package/docs/gates/checks-vendor.md +20 -13
  29. package/oxlintrc.json +1 -1
  30. package/package.json +10 -21
  31. package/scripts/ci-wiring.ts +28 -97
  32. package/scripts/commit-identity.ts +32 -4
  33. package/scripts/doc-rules.ts +26 -11
  34. package/scripts/doc-templates.ts +2 -1
  35. package/scripts/docs.ts +4 -7
  36. package/scripts/gates.ts +0 -29
  37. package/scripts/git.ts +24 -1
  38. package/scripts/lint.ts +15 -34
  39. package/scripts/range-gate.ts +1 -2
  40. package/scripts/repetition.ts +51 -40
  41. package/scripts/shell-command.ts +7 -1
  42. package/scripts/swc.ts +46 -0
  43. package/scripts/test-layout.ts +40 -56
  44. package/scripts/test-skips.ts +180 -0
  45. package/scripts/test.ts +33 -38
  46. package/scripts/vendor.ts +55 -11
  47. package/dist/feature-rules.js +0 -354
  48. package/docs/configs/quality-file.md +0 -103
  49. package/docs/gates/checks-feature-owners.md +0 -113
  50. package/docs/gates/checks-quality.md +0 -111
  51. package/docs/gates/checks-size-budget.md +0 -107
  52. package/quality.schema.json +0 -514
  53. package/scripts/feature-owners.ts +0 -139
  54. package/scripts/quality-file.ts +0 -353
  55. package/scripts/quality.ts +0 -363
  56. package/scripts/size-budget.ts +0 -285
  57. package/scripts/size-rules.ts +0 -126
package/CHANGELOG.md CHANGED
@@ -2,13 +2,39 @@
2
2
 
3
3
  Every release of `@avi2dg/checks`, newest first, written by the release from its conventional commits.
4
4
 
5
+ ## 0.23.0
6
+
7
+ Released 2026-09-26.
8
+
9
+ ### Breaking changes
10
+
11
+ - move cognitive-complexity into its own readability oxlint plugin [#74](https://github.com/avi2d/checks/pull/74)
12
+
13
+ ## 0.22.0
14
+
15
+ Released 2026-09-26.
16
+
17
+ ### Breaking changes
18
+
19
+ - replace quality.json with native configs and workflow gates [#72](https://github.com/avi2d/checks/pull/72)
20
+ - declare test skips inline and add live and pixel test tiers [#71](https://github.com/avi2d/checks/pull/71)
21
+
22
+ ### Features
23
+
24
+ - create GitHub releases with linked changelogs [#70](https://github.com/avi2d/checks/pull/70)
25
+
26
+ ### Fixes
27
+
28
+ - **scripts:** run generated commitlint through bun so the runner needs no node [#69](https://github.com/avi2d/checks/pull/69)
29
+ - **test:** allow npm pack enough time on release runners [#68](https://github.com/avi2d/checks/pull/68)
30
+
5
31
  ## 0.21.0
6
32
 
7
33
  Released 2026-09-26.
8
34
 
9
35
  ### Features
10
36
 
11
- - **scripts:** let quality.json set the runs-on of generated workflows (#66)
37
+ - **scripts:** let quality.json set the runs-on of generated workflows [#66](https://github.com/avi2d/checks/pull/66)
12
38
 
13
39
  ## 0.20.0
14
40
 
@@ -16,12 +42,12 @@ Released 2026-09-26.
16
42
 
17
43
  ### Features
18
44
 
19
- - **scripts:** pin node from .node-version in the generated CI workflow (#64)
20
- - **scripts:** add checks-subsumed-tests to report tests another test subsumes in a (#62)
45
+ - **scripts:** pin node from .node-version in the generated CI workflow [#64](https://github.com/avi2d/checks/pull/64)
46
+ - **scripts:** add checks-subsumed-tests to report tests another test subsumes in a [#62](https://github.com/avi2d/checks/pull/62)
21
47
 
22
48
  ### Fixes
23
49
 
24
- - **scripts:** lint a PR title that starts with # in the generated commitlint workflow (#63)
50
+ - **scripts:** lint a PR title that starts with # in the generated commitlint workflow [#63](https://github.com/avi2d/checks/pull/63)
25
51
 
26
52
  ## 0.19.0
27
53
 
@@ -29,9 +55,9 @@ Released 2026-09-26.
29
55
 
30
56
  ### Features
31
57
 
32
- - **scripts:** judge checks-mutation-compare mutant by mutant instead of by score (#58)
33
- - **scripts:** fail a test left in tests/quarantine past 30 days (#59)
34
- - **scripts:** pin shared read-only library clones with checks-vendor (#57)
58
+ - **scripts:** judge checks-mutation-compare mutant by mutant instead of by score [#58](https://github.com/avi2d/checks/pull/58)
59
+ - **scripts:** fail a test left in tests/quarantine past 30 days [#59](https://github.com/avi2d/checks/pull/59)
60
+ - **scripts:** pin shared read-only library clones with checks-vendor [#57](https://github.com/avi2d/checks/pull/57)
35
61
 
36
62
  ## 0.18.0
37
63
 
@@ -39,11 +65,11 @@ Released 2026-09-26.
39
65
 
40
66
  ### Features
41
67
 
42
- - **scripts:** generate commitlint and CI workflows with checks-quality (#54)
68
+ - **scripts:** generate commitlint and CI workflows with checks-quality [#54](https://github.com/avi2d/checks/pull/54)
43
69
 
44
70
  ### Fixes
45
71
 
46
- - **scripts:** make checks-quality refuse a config that drops the kit's extends (#55)
72
+ - **scripts:** make checks-quality refuse a config that drops the kit's extends [#55](https://github.com/avi2d/checks/pull/55)
47
73
 
48
74
  ## 0.17.0
49
75
 
@@ -51,9 +77,9 @@ Released 2026-09-25.
51
77
 
52
78
  ### Features
53
79
 
54
- - **effect-channel:** add a cognitive complexity rule and make it the size budget's (#50)
55
- - **scripts:** export the refused directive names from comment-matchers (#49)
56
- - refuse undeclared package imports and deprecated symbol use (#48)
80
+ - **effect-channel:** add a cognitive complexity rule and make it the size budget's [#50](https://github.com/avi2d/checks/pull/50)
81
+ - **scripts:** export the refused directive names from comment-matchers [#49](https://github.com/avi2d/checks/pull/49)
82
+ - refuse undeclared package imports and deprecated symbol use [#48](https://github.com/avi2d/checks/pull/48)
57
83
 
58
84
  ## 0.16.0
59
85
 
@@ -61,8 +87,8 @@ Released 2026-09-25.
61
87
 
62
88
  ### Features
63
89
 
64
- - **scripts:** add checks-repetition to hold new repetition in production code (#46)
65
- - **scripts:** add the recommended size limits, a tests budget and an overrun ratchet (#45)
90
+ - **scripts:** add checks-repetition to hold new repetition in production code [#46](https://github.com/avi2d/checks/pull/46)
91
+ - **scripts:** add the recommended size limits, a tests budget and an overrun ratchet [#45](https://github.com/avi2d/checks/pull/45)
66
92
 
67
93
  ## 0.15.0
68
94
 
@@ -70,7 +96,7 @@ Released 2026-09-25.
70
96
 
71
97
  ### Features
72
98
 
73
- - **scripts:** hold living docs to prose rules and resolvable references in checks-docs (#42)
99
+ - **scripts:** hold living docs to prose rules and resolvable references in checks-docs [#42](https://github.com/avi2d/checks/pull/42)
74
100
 
75
101
  ## 0.14.0
76
102
 
@@ -78,8 +104,8 @@ Released 2026-09-25.
78
104
 
79
105
  ### Features
80
106
 
81
- - **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page (#39)
82
- - **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package (#40)
107
+ - **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page [#39](https://github.com/avi2d/checks/pull/39)
108
+ - **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package [#40](https://github.com/avi2d/checks/pull/40)
83
109
 
84
110
  ## 0.13.0
85
111
 
@@ -87,7 +113,7 @@ Released 2026-09-25.
87
113
 
88
114
  ### Features
89
115
 
90
- - **scripts:** add checks-docs gate holding doc files to shared templates (#37)
116
+ - **scripts:** add checks-docs gate holding doc files to shared templates [#37](https://github.com/avi2d/checks/pull/37)
91
117
 
92
118
  ## 0.12.0
93
119
 
@@ -95,11 +121,11 @@ Released 2026-09-24.
95
121
 
96
122
  ### Features
97
123
 
98
- - **scripts:** add size budget, feature-owner rules and change-signal gates (#35)
124
+ - **scripts:** add size budget, feature-owner rules and change-signal gates [#35](https://github.com/avi2d/checks/pull/35)
99
125
 
100
126
  ### Fixes
101
127
 
102
- - release 0.12.0 and read local exports in checks-feature-owners (#36)
128
+ - release 0.12.0 and read local exports in checks-feature-owners [#36](https://github.com/avi2d/checks/pull/36)
103
129
 
104
130
  ## 0.11.0
105
131
 
@@ -107,7 +133,7 @@ Released 2026-09-24.
107
133
 
108
134
  ### Features
109
135
 
110
- - **scripts:** add quality.json with schema, loader and checks-quality fragment generator (#33)
136
+ - **scripts:** add quality.json with schema, loader and checks-quality fragment generator [#33](https://github.com/avi2d/checks/pull/33)
111
137
 
112
138
  ## 0.10.0
113
139
 
@@ -115,7 +141,7 @@ Released 2026-09-24.
115
141
 
116
142
  ### Features
117
143
 
118
- - **scripts:** add checks-test skip gate and checks-flake seed recorder (#31)
144
+ - **scripts:** add checks-test skip gate and checks-flake seed recorder [#31](https://github.com/avi2d/checks/pull/31)
119
145
 
120
146
  ## 0.9.0
121
147
 
@@ -123,14 +149,14 @@ Released 2026-09-24.
123
149
 
124
150
  ### Features
125
151
 
126
- - **scripts:** let ciWiring.lintGates select the gates checks-lint runs (#29)
127
- - **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion (#26)
152
+ - **scripts:** let ciWiring.lintGates select the gates checks-lint runs [#29](https://github.com/avi2d/checks/pull/29)
153
+ - **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion [#26](https://github.com/avi2d/checks/pull/26)
128
154
 
129
155
  ### Fixes
130
156
 
131
- - **scripts:** split Effect-free comment matchers out for hosts without node_modules (#30)
132
- - **scripts:** judge a repository's first commit against the empty tree in the range gates (#28)
133
- - **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk (#27)
157
+ - **scripts:** split Effect-free comment matchers out for hosts without node_modules [#30](https://github.com/avi2d/checks/pull/30)
158
+ - **scripts:** judge a repository's first commit against the empty tree in the range gates [#28](https://github.com/avi2d/checks/pull/28)
159
+ - **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk [#27](https://github.com/avi2d/checks/pull/27)
134
160
 
135
161
  ## 0.8.0
136
162
 
@@ -138,8 +164,8 @@ Released 2026-09-24.
138
164
 
139
165
  ### Features
140
166
 
141
- - **scripts:** add checks-lint to run every kit lint gate over one resolved range (#25)
142
- - **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO (#22)
167
+ - **scripts:** add checks-lint to run every kit lint gate over one resolved range [#25](https://github.com/avi2d/checks/pull/25)
168
+ - **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO [#22](https://github.com/avi2d/checks/pull/22)
143
169
 
144
170
  ## 0.6.0
145
171
 
@@ -147,7 +173,7 @@ Released 2026-09-24.
147
173
 
148
174
  ### Features
149
175
 
150
- - add checks-suppressions-ratchet to refuse a raised oxlint suppression count (#21)
176
+ - add checks-suppressions-ratchet to refuse a raised oxlint suppression count [#21](https://github.com/avi2d/checks/pull/21)
151
177
 
152
178
  ## 0.5.0
153
179
 
@@ -155,7 +181,7 @@ Released 2026-09-24.
155
181
 
156
182
  ### Features
157
183
 
158
- - **effect-channel:** add opt-in no-throw and no-try-catch rules (#20)
184
+ - **effect-channel:** add opt-in no-throw and no-try-catch rules [#20](https://github.com/avi2d/checks/pull/20)
159
185
 
160
186
  ## 0.4.0
161
187
 
@@ -163,11 +189,11 @@ Released 2026-09-24.
163
189
 
164
190
  ### Features
165
191
 
166
- - add checks-ci-wiring to confirm CI runs each declared gate on pull requests (#19)
192
+ - add checks-ci-wiring to confirm CI runs each declared gate on pull requests [#19](https://github.com/avi2d/checks/pull/19)
167
193
 
168
194
  ### Fixes
169
195
 
170
- - pin the quarantine pathIgnorePatterns in the test-layout bunfig check (#18)
196
+ - pin the quarantine pathIgnorePatterns in the test-layout bunfig check [#18](https://github.com/avi2d/checks/pull/18)
171
197
 
172
198
  ## 0.3.0
173
199
 
@@ -175,8 +201,8 @@ Released 2026-09-23.
175
201
 
176
202
  ### Features
177
203
 
178
- - add checks-mutation-compare no-regression gate for Stryker reports (#17)
179
- - ship a shared Stryker mutation-testing preset (#16)
204
+ - add checks-mutation-compare no-regression gate for Stryker reports [#17](https://github.com/avi2d/checks/pull/17)
205
+ - ship a shared Stryker mutation-testing preset [#16](https://github.com/avi2d/checks/pull/16)
180
206
 
181
207
  ## 0.2.0
182
208
 
@@ -184,11 +210,11 @@ Released 2026-09-23.
184
210
 
185
211
  ### Features
186
212
 
187
- - expose runnable scripts as checks- bins for consumer package scripts (#15)
188
- - rename npm package from @avi2d/checks to @avi2dg/checks (#14)
189
- - add a shared comment gate and backtest command (#12)
190
- - publish @avi2d/checks to the public npm registry (#11)
213
+ - expose runnable scripts as checks- bins for consumer package scripts [#15](https://github.com/avi2d/checks/pull/15)
214
+ - rename npm package from @avi2d/checks to @avi2dg/checks [#14](https://github.com/avi2d/checks/pull/14)
215
+ - add a shared comment gate and backtest command [#12](https://github.com/avi2d/checks/pull/12)
216
+ - publish @avi2d/checks to the public npm registry [#11](https://github.com/avi2d/checks/pull/11)
191
217
 
192
218
  ### Fixes
193
219
 
194
- - count violation lines from file top, drop dead moduleStart (#10)
220
+ - count violation lines from file top, drop dead moduleStart [#10](https://github.com/avi2d/checks/pull/10)
package/CONTRIBUTING.md CHANGED
@@ -16,7 +16,9 @@ To check a change the way CI does:
16
16
  1. Run `bun run typecheck`.
17
17
  1. Run `bun run test`, which runs the suite through `scripts/test.ts`.
18
18
 
19
- CI runs the commands `gates.ci` lists in `quality.json`, which include `git diff --exit-code` over the whole tree after the build and the commit lint on the pull request title.
19
+ Declare each skip with `skipReason(reason, name)` beside the native Bun test call, as [checks-test](docs/gates/checks-test.md) says.
20
+
21
+ CI runs the commands in `.github/workflows/ci.yml` and lints the pull request title in `.github/workflows/commitlint.yml`.
20
22
 
21
23
  ## Regenerate what is committed
22
24
 
@@ -24,9 +26,8 @@ Each generated file is committed, and lint, the suite or CI's diff after the bui
24
26
 
25
27
  To regenerate after an edit:
26
28
 
27
- 1. After editing `sources.effect` in `quality.json` or a file in `presets/`, run `bun scripts/quality.ts generate`, which rewrites `oxlintrc.quality.json` and `tsconfig.quality.json`.
28
- 1. After editing `effect-channel/`, `scripts/feature-rules.ts`, the schema in `scripts/quality-file.ts` or the templates in `scripts/doc-templates.ts`, run `bun run build`.
29
- It rewrites `dist/index.js`, `dist/feature-rules.js`, `quality.schema.json` and `templates/`.
29
+ 1. After editing `effect-channel/`, `readability/` or the templates in `scripts/doc-templates.ts`, run `bun run build`.
30
+ It rewrites `dist/` and `templates/`.
30
31
  1. After editing anything a generated block names as its source in its opening marker, run `bun run build`, which rewrites every generated block.
31
32
  1. Commit what the command rewrote in the same commit as the edit.
32
33
 
@@ -49,7 +50,9 @@ To release a version:
49
50
  ```
50
51
 
51
52
  1. Watch the `release` workflow.
52
- It refuses a tag off `main` or one that disagrees with `package.json`, and reruns the build, the check that the build changed no committed file, lint, typecheck and the suite before it publishes.
53
+ It refuses a tag off `main` or one that disagrees with `package.json`.
54
+ It reruns the build, the check that the build changed no committed file, lint, typecheck and the suite before it publishes to npm.
55
+ After npm publish succeeds, the workflow creates or updates the GitHub release with the matching `CHANGELOG.md` section.
53
56
 
54
57
  `publishConfig.access` in `package.json` is what makes the scoped package public.
55
58
  npm attaches a trusted publisher only to a package that already exists, so a package's first version goes out by hand.
@@ -65,22 +68,23 @@ To place a change:
65
68
  | Path | What it holds |
66
69
  | --- | --- |
67
70
  | `scripts/` | every bin, and the modules they share |
68
- | `effect-channel/` | the oxlint plugin with the Effect error-channel and cognitive complexity rules |
69
- | `dist/` | the committed bundles of the plugin and of `featureRules` |
70
- | `presets/` | the Effect presets `checks-quality` builds its fragments from |
71
+ | `effect-channel/` | the oxlint plugin with the Effect error-channel rules |
72
+ | `readability/` | the oxlint plugin with the readability rules |
73
+ | `dist/` | the committed oxlint plugin bundles |
74
+ | `presets/` | the Effect rule blocks consumers copy into native configs |
71
75
  | `templates/` | one template per kind of doc file, which `bun run build` renders |
72
76
  | `CHANGELOG.md` | every release, which `bun run build` writes from the conventional commits |
73
77
  | `tests/` | the suite, with the tests that spawn a process under `tests/e2e/` |
74
78
  | `docs/gates/` | one reference page per bin |
75
79
  | `docs/configs/` | one reference page per shipped config a bin does not own |
76
80
  | `docs/design.md` | why the kit is shaped the way it is |
77
- | the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js` and `quality.schema.json`, which a consuming repository extends or copies |
81
+ | the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js`, which a consuming repository extends or copies |
78
82
 
79
83
  1. Change the page under `docs/` that describes the behaviour in the same commit as the behaviour.
80
84
  A new bin gets its page under `docs/gates/`, and the suite fails until it has one.
81
85
 
82
86
  This repository holds itself to the kit, with two exceptions of its own.
83
- Its `.dependency-cruiser.cjs` redeclares `no-orphans` with the plugin entry added to its `pathNot`.
87
+ Its `.dependency-cruiser.cjs` redeclares `no-orphans` with each plugin entry added to its `pathNot`.
84
88
  Its `.oxlintrc.json` lifts `effect-channel/no-throw` from `scripts/comment-matchers.ts`, whose synchronous `refused()` a host loads without `node_modules`.
85
89
 
86
90
  ## Related topics
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `@avi2dg/checks` is the kit of deterministic checks a TypeScript repository installs to hold its code, tests, commits, CI wiring and docs to one shared standard.
4
4
  It ships the lint gates `checks-lint` runs over each pull request, the test runners, and the configs a repository extends for oxlint, tsc, dependency-cruiser, commitlint, bun and Stryker.
5
- A repository declares what it opts into once, in `quality.json`, and each check decides its constraint the same way on every run.
5
+ Each repository owns its workflows and native tool configs, as [Native settings](docs/configs/native-settings.md) maps.
6
6
 
7
7
  ## Before you begin
8
8
 
@@ -59,30 +59,22 @@ To consume the kit from a repository:
59
59
  }
60
60
  ```
61
61
 
62
- 1. Declare the commands CI runs in `quality.json` at the repository root:
63
-
64
- ```json
65
- {
66
- "$schema": "./node_modules/@avi2dg/checks/quality.schema.json",
67
- "gates": { "ci": ["bun run lint", "bun run typecheck", "bun run test"] }
68
- }
69
- ```
70
-
71
62
  1. Copy the bunfig preset:
72
63
 
73
64
  ```sh
74
65
  cp node_modules/@avi2dg/checks/bunfig.toml bunfig.toml
75
66
  ```
76
67
 
77
- 1. Add three scripts to `package.json`:
68
+ 1. Add scripts to `package.json`, replacing the build entry with the repository's own build command:
78
69
 
79
70
  ```json
71
+ "build": "bun build src/index.ts --outdir dist --target node",
80
72
  "lint": "oxlint --type-aware && checks-lint",
81
73
  "typecheck": "tsc --noEmit && effect-tsgo diagnostics --project tsconfig.json --format text --strict",
82
74
  "test": "checks-test"
83
75
  ```
84
76
 
85
- 1. Run the three on every pull request in `.github/workflows/ci.yml`, fetching the whole history the range needs:
77
+ 1. Run the scripts on every pull request in `.github/workflows/ci.yml`, fetching the whole history the range needs:
86
78
 
87
79
  ```yaml
88
80
  on:
@@ -96,17 +88,20 @@ To consume the kit from a repository:
96
88
  fetch-depth: 0
97
89
  - uses: oven-sh/setup-bun@v2
98
90
  - run: bun install --frozen-lockfile
91
+ - run: bun run build
92
+ - run: git diff --exit-code
99
93
  - run: bun run lint
100
94
  - run: bun run typecheck
101
95
  - run: bun run test
102
96
  ```
103
97
 
98
+ Add a pull request title lint step in another workflow using `./node_modules/.bin/commitlint`.
104
99
  `bun run lint` then ends with `checks-lint: <count> gate(s) pass`.
105
100
 
106
101
  ## What runs
107
102
 
108
103
  `checks-lint` runs these gates in this order, each over the working tree or over the range it resolves, and names every one that fails.
109
- A repository leaves out a gate that does not apply to it through `gates.lint`, as [Gate selection](docs/gates/checks-lint.md#gate-selection) says.
104
+ `checks-lint` runs every applicable gate, including the TypeScript gates once the repository tracks TypeScript.
110
105
 
111
106
  <!-- generated gates: bun run build writes it from KIT_GATES in scripts/gates.ts and scripts/doc-blocks.ts -->
112
107
 
@@ -119,22 +114,19 @@ A repository leaves out a gate that does not apply to it through `gates.lint`, a
119
114
  | [`checks-suppressions-ratchet`](docs/gates/checks-suppressions-ratchet.md) | the range | every repository |
120
115
  | [`checks-ci-wiring`](docs/gates/checks-ci-wiring.md) | the working tree | every repository |
121
116
  | [`checks-docs`](docs/gates/checks-docs.md) | the range | every repository |
122
- | [`checks-quality`](docs/gates/checks-quality.md) | the working tree | a repository tracking `quality.json` |
123
- | [`checks-size-budget`](docs/gates/checks-size-budget.md) | the range | a repository tracking `*.ts` or `*.tsx` |
124
117
  | [`checks-repetition`](docs/gates/checks-repetition.md) | the range | a repository tracking `*.ts` or `*.tsx` |
125
- | [`checks-feature-owners`](docs/gates/checks-feature-owners.md) | the range | a repository tracking `*.ts` or `*.tsx` |
126
118
  | [`checks-quarantine-clock`](docs/gates/checks-quarantine-clock.md) | the range | every repository |
127
119
 
128
120
  <!-- end generated gates -->
129
121
 
130
122
  These bins run on their own:
131
123
 
132
- - [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip the repository has not declared.
124
+ - [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip without a reason at its test site.
133
125
  - [`checks-flake`](docs/gates/checks-flake.md) runs the suite on a schedule and records the seeds a flaky test fails with.
134
126
  - [`checks-mutation-compare`](docs/gates/checks-mutation-compare.md) holds every mutant in a pull request to no regression.
135
127
  - [`checks-subsumed-tests`](docs/gates/checks-subsumed-tests.md) lists each test another test subsumes in a mutation run.
136
128
  - [`checks-backtest`](docs/gates/checks-backtest.md) reports what the comment check would have refused in recent history.
137
- - [`checks-vendor`](docs/gates/checks-vendor.md) pins each library `quality.json` declares to a shared read-only clone and links it under `repos/`.
129
+ - [`checks-vendor`](docs/gates/checks-vendor.md) pins each library its `prepare` arguments name to a shared read-only clone and links it under `repos/`.
138
130
 
139
131
  `checks-lint` has [its own page](docs/gates/checks-lint.md), which says which range it resolves.
140
132
  The oxlint base, the dependency-cruiser base and the commitlint config run through their own tools, as the pages under Related topics say.
@@ -144,13 +136,13 @@ The oxlint base, the dependency-cruiser base and the commitlint config run throu
144
136
  To move a repository to a newer release of the kit:
145
137
 
146
138
  1. Run the install line again, which moves the kit to its newest release and the peers to the versions it pins.
147
- 1. Run `bun run checks-quality generate` when `quality.json` declares `sources.effect`, since a release that changes a preset reaches the fragments only through it.
139
+ 1. Review the Effect overrides in `.oxlintrc.json` and `tsconfig.json` when a release changes their presets.
148
140
  1. Copy `node_modules/@avi2dg/checks/bunfig.toml` over `bunfig.toml` again, since `checks-test-layout` compares the copy with the installed preset.
149
141
  1. Run `bun run lint`, `bun run typecheck` and `bun run test`.
150
142
 
151
143
  The repository's lockfile pins the kit, so a repository moves only when it runs these steps.
152
144
  [CHANGELOG.md](CHANGELOG.md), shipped in the package, lists what each release changed.
153
- A repository that still declares `ciWiring` or `commitIdentity` in `package.json` moves them into `quality.json`, as [Keys moved from package.json](docs/configs/quality-file.md#keys-moved-from-packagejson) maps.
145
+ A repository that tracks `quality.json` moves its settings as [Native settings](docs/configs/native-settings.md#consumer-migration) maps.
154
146
 
155
147
  ## Where things are
156
148
 
@@ -168,18 +160,17 @@ Every path is relative to the installed package, `node_modules/@avi2dg/checks/`.
168
160
  | `dependency-cruiser.config.js` | the shared dependency-cruiser base |
169
161
  | `scripts/` | every bin, which a package script calls by its `checks-` name |
170
162
  | `templates/` | one template per kind of doc file, which a new doc file starts from |
171
- | `presets/` | the Effect rule blocks `checks-quality generate` writes into the fragments |
172
- | `quality.schema.json` | the schema of `quality.json`, which its `$schema` line names |
163
+ | `presets/` | the Effect rule blocks a repository copies into its native config |
173
164
  | `oxlintrc.json` | the oxlint base config `.oxlintrc.json` extends |
174
165
  | `stryker.preset.js` | the Stryker mutation-testing preset |
175
166
  | `tsconfig.effect.json` | the tsconfig fragment with the Effect language-service block |
176
- | `dist/` | the compiled oxlint plugin with the Effect error-channel and cognitive complexity rules, and `featureRules` |
167
+ | `dist/` | the compiled oxlint plugins, one per purpose |
177
168
 
178
169
  <!-- end generated shipped -->
179
170
 
180
171
  ## Related topics
181
172
 
182
- - [The quality file](docs/configs/quality-file.md)
173
+ - [Native settings](docs/configs/native-settings.md)
183
174
  - [The Effect rules](docs/configs/effect-rules.md)
184
175
  - [The TypeScript rules](docs/configs/typescript-rules.md)
185
176
  - [The dependency rules](docs/configs/dependency-rules.md)
package/bunfig.toml CHANGED
@@ -1,2 +1,2 @@
1
1
  [test]
2
- pathIgnorePatterns = ["**/tests/quarantine/**", "repos/**"]
2
+ pathIgnorePatterns = ["**/tests/quarantine/**", "**/tests/live/**", "**/tests/pixel/**", "repos/**"]
@@ -0,0 +1,122 @@
1
+ // effect-channel/no-error-channel-escape.ts
2
+ var EFFECT_SOURCES = new Set(["effect", "effect/Effect"]);
3
+ var INSTEAD = {
4
+ drops: "it drops the failure and the success together, so no caller can tell one from the other. Handle the error by tag, or keep it as a value with Effect.result or Effect.exit",
5
+ swallows: "a Cause is the typed error plus defects plus interruption, so this swallows the bugs and the cancellations along with it. Catch the errors you named, with Effect.catchTag or Effect.catchTags",
6
+ blind: "the handler cannot see what it is recovering from, so every error in the channel collapses into one fallback. Name the errors with Effect.catchTag, or take the error and use it"
7
+ };
8
+ var REFUSED = new Map([
9
+ ["ignore", INSTEAD.drops],
10
+ ["ignoreCause", INSTEAD.drops],
11
+ ["catchCause", INSTEAD.swallows],
12
+ ["catchCauseIf", INSTEAD.swallows],
13
+ ["catchCauseFilter", INSTEAD.swallows]
14
+ ]);
15
+ var blindToTheError = (handler) => {
16
+ if (!handler)
17
+ return false;
18
+ if (handler.type !== "ArrowFunctionExpression" && handler.type !== "FunctionExpression")
19
+ return false;
20
+ return handler.params.every((param) => param.type === "Identifier" && /^_+$/.test(param.name));
21
+ };
22
+ var rule = {
23
+ meta: {
24
+ type: "problem",
25
+ docs: { description: "Disallow the combinators that erase Effect's error channel" }
26
+ },
27
+ create(context) {
28
+ const effect = new Set;
29
+ const named = (node) => {
30
+ if (!node || node.type !== "MemberExpression" || node.computed)
31
+ return null;
32
+ if (node.object.type !== "Identifier" || !effect.has(node.object.name))
33
+ return null;
34
+ return node.property.type === "Identifier" ? node.property.name : null;
35
+ };
36
+ const refuse = (node, combinator, instead) => {
37
+ context.report({ node, message: `Effect.${combinator} erases the error channel: ${instead}` });
38
+ };
39
+ return {
40
+ ImportDeclaration(node) {
41
+ if (!EFFECT_SOURCES.has(node.source.value))
42
+ return;
43
+ const module = node.source.value === "effect/Effect";
44
+ for (const specifier of node.specifiers) {
45
+ if (specifier.type === "ImportSpecifier") {
46
+ if (specifier.imported.type === "Identifier" && specifier.imported.name === "Effect")
47
+ effect.add(specifier.local.name);
48
+ } else if (module)
49
+ effect.add(specifier.local.name);
50
+ }
51
+ },
52
+ MemberExpression(node) {
53
+ const combinator = named(node);
54
+ if (combinator === null)
55
+ return;
56
+ const instead = REFUSED.get(combinator);
57
+ if (instead !== undefined)
58
+ refuse(node, combinator, instead);
59
+ },
60
+ CallExpression(node) {
61
+ if (named(node.callee) !== "catch")
62
+ return;
63
+ if (!blindToTheError(node.arguments[node.arguments.length - 1]))
64
+ return;
65
+ refuse(node, "catch", INSTEAD.blind);
66
+ }
67
+ };
68
+ }
69
+ };
70
+ var no_error_channel_escape_default = rule;
71
+
72
+ // effect-channel/no-throw.ts
73
+ var rule2 = {
74
+ meta: {
75
+ type: "problem",
76
+ docs: { description: "Disallow throw, which fails outside Effect's error channel" }
77
+ },
78
+ create(context) {
79
+ return {
80
+ ThrowStatement(node) {
81
+ context.report({
82
+ node,
83
+ message: "throw escapes the error channel: no type records the failure, so no caller has to answer for it. Define the failure with Schema.TaggedError and fail with it through Effect.fail, so it stays in E for Effect.catchTag to handle"
84
+ });
85
+ }
86
+ };
87
+ }
88
+ };
89
+ var no_throw_default = rule2;
90
+
91
+ // effect-channel/no-try-catch.ts
92
+ var rule3 = {
93
+ meta: {
94
+ type: "problem",
95
+ docs: { description: "Disallow a try statement with a catch clause, which recovers outside Effect's error channel" }
96
+ },
97
+ create(context) {
98
+ return {
99
+ CatchClause(node) {
100
+ context.report({
101
+ node,
102
+ message: "catch recovers outside the error channel: it takes whatever was thrown as unknown, bugs included. Wrap the throwing call in Effect.try or Effect.tryPromise, whose catch maps the cause to a Schema.TaggedError, and recover by tag with Effect.catchTag"
103
+ });
104
+ }
105
+ };
106
+ }
107
+ };
108
+ var no_try_catch_default = rule3;
109
+
110
+ // effect-channel/index.ts
111
+ var plugin = {
112
+ meta: { name: "effect-channel" },
113
+ rules: {
114
+ "no-error-channel-escape": no_error_channel_escape_default,
115
+ "no-throw": no_throw_default,
116
+ "no-try-catch": no_try_catch_default
117
+ }
118
+ };
119
+ var effect_channel_default = plugin;
120
+ export {
121
+ effect_channel_default as default
122
+ };